diff options
author | anika-ahluwalia <anika.ahluwalia@gmail.com> | 2020-04-14 18:35:13 -0500 |
---|---|---|
committer | anika-ahluwalia <anika.ahluwalia@gmail.com> | 2020-04-14 18:35:13 -0500 |
commit | 7bef084dc56d499d45cbd94bfedbcd3c49bfe854 (patch) | |
tree | 058cf84c615e23baf96e1324304dee312f1a913f /src | |
parent | 15316764dfcc1d230efdc6cd2f2f0bd47be3efd8 (diff) | |
parent | c3c63effcdd9068c4ed5968a4a66f881957c8cb8 (diff) |
Merge branch 'master' of https://github.com/browngraphicslab/Dash-Web into script_documents
Diffstat (limited to 'src')
-rw-r--r-- | src/client/views/collections/CollectionMapView.tsx | 93 | ||||
-rw-r--r-- | src/client/views/nodes/DocumentView.tsx | 10 | ||||
-rw-r--r-- | src/client/views/nodes/ScriptingBox.tsx | 5 |
3 files changed, 59 insertions, 49 deletions
diff --git a/src/client/views/collections/CollectionMapView.tsx b/src/client/views/collections/CollectionMapView.tsx index b6772c5a2..64946e59e 100644 --- a/src/client/views/collections/CollectionMapView.tsx +++ b/src/client/views/collections/CollectionMapView.tsx @@ -1,6 +1,6 @@ import { GoogleApiWrapper, Map as GeoMap, MapProps, Marker } from "google-maps-react"; import { observer } from "mobx-react"; -import { Doc, Opt, DocListCast } from "../../../new_fields/Doc"; +import { Doc, Opt, DocListCast, FieldResult } from "../../../new_fields/Doc"; import { documentSchema } from "../../../new_fields/documentSchemas"; import { Id } from "../../../new_fields/FieldSymbols"; import { makeInterface } from "../../../new_fields/Schema"; @@ -28,7 +28,11 @@ const defaultLocation = { lat: 35.1592238, lng: -98.444512, zoom: 15 }; const query = async (data: string | google.maps.LatLngLiteral) => { const contents = typeof data === "string" ? `address=${data.replace(/\s+/g, "+")}` : `latlng=${data.lat},${data.lng}`; const target = `https://maps.googleapis.com/maps/api/geocode/json?${contents}&key=${process.env.GOOGLE_MAPS_GEO}`; - return JSON.parse(await requestPromise.get(target)); + try { + return JSON.parse(await requestPromise.get(target)); + } catch { + return undefined; + } }; @observer @@ -36,6 +40,7 @@ class CollectionMapView extends CollectionSubView<MapSchema, Partial<MapProps> & private _cancelAddrReq = new Map<string, boolean>(); private _cancelLocReq = new Map<string, boolean>(); + private _initialLookupPending = new Map<string, boolean>(); private addressUpdaters: IReactionDisposer[] = []; private latlngUpdaters: IReactionDisposer[] = []; @@ -47,7 +52,7 @@ class CollectionMapView extends CollectionSubView<MapSchema, Partial<MapProps> & * and address–updating reactions. */ - getLocation = (doc: Opt<Doc>, fieldKey: string): Opt<LocationData> => { + private getLocation = (doc: Opt<Doc>, fieldKey: string): Opt<LocationData> => { if (doc) { const lat: Opt<number> = Cast(doc[fieldKey + "-lat"], "number", null) || (Cast(doc[fieldKey + "-lat"], "string", null) && Number(Cast(doc[fieldKey + "-lat"], "string", null))) || undefined; const lng: Opt<number> = Cast(doc[fieldKey + "-lng"], "number", null) || (Cast(doc[fieldKey + "-lng"], "string", null) && Number(Cast(doc[fieldKey + "-lng"], "string", null))) || undefined; @@ -56,19 +61,13 @@ class CollectionMapView extends CollectionSubView<MapSchema, Partial<MapProps> & if (lat !== undefined && lng !== undefined) { return ({ lat, lng, zoom }); } else if (address) { - setTimeout(() => { - query(address).then(({ results }) => { - if (results?.length) { - const { lat, lng } = results[0].geometry.location; - if (doc[fieldKey + "-lat"] !== lat || doc[fieldKey + "-lng"] !== lng) { - runInAction(() => { - Doc.SetInPlace(doc, fieldKey + "-lat", lat, true); - Doc.SetInPlace(doc, fieldKey + "-lng", lng, true); - }); - } - } + const id = doc[Id]; + if (!this._initialLookupPending.get(id)) { + this._initialLookupPending.set(id, true); + setTimeout(() => { + this.respondToAddressChange(address, doc).then(() => this._initialLookupPending.delete(id)); }); - }); + } return defaultLocation; } } @@ -93,7 +92,7 @@ class CollectionMapView extends CollectionSubView<MapSchema, Partial<MapProps> & } } - renderMarkerIcon(layout: Doc) { + private renderMarkerIcon = (layout: Doc) => { const iconUrl = StrCast(this.props.Document.mapIconUrl, null); if (iconUrl) { const iconWidth = NumCast(layout["mapLocation-iconWidth"], 45); @@ -107,7 +106,7 @@ class CollectionMapView extends CollectionSubView<MapSchema, Partial<MapProps> & } } - renderMarker(layout: Doc) { + private renderMarker = (layout: Doc) => { const location = this.getLocation(layout, "mapLocation"); return !location ? (null) : <Marker @@ -119,6 +118,38 @@ class CollectionMapView extends CollectionSubView<MapSchema, Partial<MapProps> & />; } + private respondToAddressChange = async (newAddress: string, doc: Doc) => { + const { results } = await query(newAddress); + if (!results?.length) { + return; + } + const { geometry, formatted_address } = results[0]; + const { lat, lng } = geometry.location; + runInAction(() => { + if (doc["mapLocation-lat"] !== lat || doc["mapLocation-lng"] !== lng) { + this._cancelLocReq.set(doc[Id], true); + Doc.SetInPlace(doc, "mapLocation-lat", lat, true); + Doc.SetInPlace(doc, "mapLocation-lng", lng, true); + } + if (formatted_address !== newAddress) { + this._cancelAddrReq.set(doc[Id], true); + Doc.SetInPlace(doc, "mapLocation-address", formatted_address, true); + } + }); + } + + private respondToLocationChange = async (newLat: FieldResult, newLng: FieldResult, doc: Doc) => { + const { results } = await query({ lat: NumCast(newLat), lng: NumCast(newLng) }); + if (!results?.length) { + return; + } + const { formatted_address } = results[0]; + if (formatted_address !== doc["mapLocation-address"]) { + this._cancelAddrReq.set(doc[Id], true); + Doc.SetInPlace(doc, "mapLocation-address", formatted_address, true); + } + } + @computed get contents() { this.addressUpdaters.forEach(disposer => disposer()); this.addressUpdaters = []; @@ -131,15 +162,7 @@ class CollectionMapView extends CollectionSubView<MapSchema, Partial<MapProps> & if (this._cancelLocReq.get(layout[Id])) { this._cancelLocReq.set(layout[Id], false); } else if (lat !== undefined && lng !== undefined) { - query({ lat: NumCast(lat), lng: NumCast(lng) }).then(({ results }) => { - if (results?.length) { - const { formatted_address } = results[0]; - if (formatted_address !== layout["mapLocation-address"]) { - this._cancelAddrReq.set(layout[Id], true); - Doc.SetInPlace(layout, "mapLocation-address", formatted_address, true); - } - } - }); + this.respondToLocationChange(lat, lng, layout); } } )); @@ -149,23 +172,7 @@ class CollectionMapView extends CollectionSubView<MapSchema, Partial<MapProps> & if (this._cancelAddrReq.get(layout[Id])) { this._cancelAddrReq.set(layout[Id], false); } else if (address?.length) { - query(address).then(({ results }) => { - if (results?.length) { - const { geometry, formatted_address } = results[0]; - const { lat, lng } = geometry.location; - runInAction(() => { - if (layout["mapLocation-lat"] !== lat || layout["mapLocation-lng"] !== lng) { - this._cancelLocReq.set(layout[Id], true); - Doc.SetInPlace(layout, "mapLocation-lat", lat, true); - Doc.SetInPlace(layout, "mapLocation-lng", lng, true); - } - if (formatted_address !== address) { - this._cancelAddrReq.set(layout[Id], true); - Doc.SetInPlace(layout, "mapLocation-address", formatted_address, true); - } - }); - } - }); + this.respondToAddressChange(address, layout); } } )); diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 0ef7ece9c..cb7811fbb 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -298,7 +298,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu SelectionManager.DeselectAll(); Doc.UnBrushDoc(this.props.Document); } - } else if (this.onClickHandler?.script) { + } else if (this.onClickHandler?.script && !StrCast(Doc.LayoutField(this.layoutDoc))?.includes("ScriptingBox")) { // bcz: hack? don't execute script if you're clicking on a scripting box itself SelectionManager.DeselectAll(); const func = () => this.onClickHandler.script.run({ this: this.layoutDoc, @@ -308,8 +308,9 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu if (this.props.Document !== Doc.UserDoc().undoBtn && this.props.Document !== Doc.UserDoc().redoBtn) { UndoManager.RunInBatch(func, "on click"); } else func(); - } else if (this.Document["onClick-rawScript"]) { - UndoManager.RunInBatch(() => ScriptBox.EditButtonScript("On Button Clicked ...", this.props.Document, "onClick", e.clientX, e.clientY), "on button click"); + } else if (this.Document["onClick-rawScript"] && !StrCast(Doc.LayoutField(this.layoutDoc))?.includes("ScriptingBox")) {// bcz: hack? don't edit a script if you're clicking on a scripting box itself + UndoManager.RunInBatch(() => DocumentView.makeCustomViewClicked(this.props.Document, undefined, "onClick"), "edit onClick"); + //ScriptBox.EditButtonScript("On Button Clicked ...", this.props.Document, "onClick", e.clientX, e.clientY), "on button click"); } else if (this.Document.isLinkButton) { DocListCast(this.props.Document.links).length && this.followLinkClick(e.altKey, e.ctrlKey, e.shiftKey); } else { @@ -556,7 +557,8 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu const iconViews = DocListCast(Cast(Doc.UserDoc().iconViews, Doc, null)?.data); const templBtns = DocListCast(Cast(Doc.UserDoc().templateButtons, Doc, null)?.data); const noteTypes = DocListCast(Cast(Doc.UserDoc().noteTypes, Doc, null)?.data); - const allTemplates = iconViews.concat(templBtns).concat(noteTypes).map(btnDoc => (btnDoc.dragFactory as Doc) || btnDoc).filter(doc => doc.isTemplateDoc); + const clickFuncs = DocListCast(Cast(Doc.UserDoc().clickFuncs, Doc, null)?.data); + const allTemplates = iconViews.concat(templBtns).concat(noteTypes).concat(clickFuncs).map(btnDoc => (btnDoc.dragFactory as Doc) || btnDoc).filter(doc => doc.isTemplateDoc); // bcz: this is hacky -- want to have different templates be applied depending on the "type" of a document. but type is not reliable and there could be other types of template searches so this should be generalized // first try to find a template that matches the specific document type (<typeName>_<templateName>). otherwise, fallback to a general match on <templateName> !docLayoutTemplate && allTemplates.forEach(tempDoc => StrCast(tempDoc.title) === type + "_" + templateName && (docLayoutTemplate = tempDoc)); diff --git a/src/client/views/nodes/ScriptingBox.tsx b/src/client/views/nodes/ScriptingBox.tsx index 7fcb9a8d0..bd20f9f67 100644 --- a/src/client/views/nodes/ScriptingBox.tsx +++ b/src/client/views/nodes/ScriptingBox.tsx @@ -84,9 +84,9 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps, Sc />; return ( <div className="scriptingBox-outerDiv" - onPointerDown={e => this.props.isSelected(true) && e.stopPropagation()} onWheel={e => this.props.isSelected(true) && e.stopPropagation()}> - <div className="scriptingBox-inputDiv" > + <div className="scriptingBox-inputDiv" + onPointerDown={e => this.props.isSelected(true) && e.stopPropagation()} > <textarea className="scriptingBox-textarea" placeholder="write your script here" onChange={e => this.rawScript = e.target.value} @@ -96,6 +96,7 @@ export class ScriptingBox extends ViewBoxAnnotatableComponent<FieldViewProps, Sc <div className="scriptingBox-errorMessage" style={{ background: this._errorMessage ? "red" : "" }}>{this._errorMessage}</div> <div className="scriptingBox-params" >{params}</div> </div> + {this.rootDoc.layout === "layout" ? <div></div> : (null)} <div className="scriptingBox-toolbar"> <button className="scriptingBox-button" onPointerDown={e => { this.onCompile(); e.stopPropagation(); }}>Compile</button> <button className="scriptingBox-button" onPointerDown={e => { this.onRun(); e.stopPropagation(); }}>Run</button> |