From 2c024bd6fa6ac11f2987f2db910e35b4e2d32952 Mon Sep 17 00:00:00 2001 From: SHKnudsen Date: Mon, 1 Feb 2021 10:17:30 +0000 Subject: [PATCH 1/6] workspacemodel thumbnail api + test --- .../Workspaces/SerializationConverters.cs | 7 ++++ .../Graph/Workspaces/WorkspaceModel.cs | 24 ++++++++++++++ .../Graph/Workspaces/WorkspaceModelTests.cs | 30 ++++++++++++++++++ .../Graph/Workspaces/thumbnailTestImage.png | Bin 0 -> 5501 bytes 4 files changed, 61 insertions(+) create mode 100644 test/DynamoCoreTests/Graph/Workspaces/thumbnailTestImage.png diff --git a/src/DynamoCore/Graph/Workspaces/SerializationConverters.cs b/src/DynamoCore/Graph/Workspaces/SerializationConverters.cs index 950a1d444d7..d2d2492d1a6 100644 --- a/src/DynamoCore/Graph/Workspaces/SerializationConverters.cs +++ b/src/DynamoCore/Graph/Workspaces/SerializationConverters.cs @@ -649,6 +649,9 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist ws.NodeLibraryDependencies = nodeLibraryDependencies.ToList(); ws.ExtensionData = GetExtensionData(serializer, obj); + if (obj.TryGetValue(nameof(WorkspaceModel.Thumbnail), StringComparison.OrdinalIgnoreCase, out JToken thumbnail)) + ws.Thumbnail = thumbnail.ToString(); + return ws; } @@ -771,6 +774,10 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s writer.WritePropertyName(WorkspaceReadConverter.EXTENSION_WORKSPACE_DATA); serializer.Serialize(writer, ws.ExtensionData); + // Thumbnail + writer.WritePropertyName(nameof(WorkspaceModel.Thumbnail)); + writer.WriteValue(ws.Thumbnail); + if (engine != null) { // Bindings diff --git a/src/DynamoCore/Graph/Workspaces/WorkspaceModel.cs b/src/DynamoCore/Graph/Workspaces/WorkspaceModel.cs index b68336d6953..1e36e430f9e 100644 --- a/src/DynamoCore/Graph/Workspaces/WorkspaceModel.cs +++ b/src/DynamoCore/Graph/Workspaces/WorkspaceModel.cs @@ -724,6 +724,30 @@ public string Description } } + private string thumbnail; + + /// + /// Workspace thumbnail as Base64 string. + /// Returns null if provide value is not Base64 encoded. + /// + public string Thumbnail + { + get { return thumbnail; } + set + { + try + { + // if value is not a valid Base64 string this will throw, and we return null. + byte[] data = Convert.FromBase64String(value); + thumbnail = value; + } + catch + { + return; + } + } + } + /// /// List of user defined data from extensions and view extensions stored in the graph /// diff --git a/test/DynamoCoreTests/Graph/Workspaces/WorkspaceModelTests.cs b/test/DynamoCoreTests/Graph/Workspaces/WorkspaceModelTests.cs index 4974f2a7e98..a94dd825e39 100644 --- a/test/DynamoCoreTests/Graph/Workspaces/WorkspaceModelTests.cs +++ b/test/DynamoCoreTests/Graph/Workspaces/WorkspaceModelTests.cs @@ -284,5 +284,35 @@ public void UpdateModelValueInvalidParameters() Assert.AreEqual(Resources.ModelNotFoundError, ex3.Message); } + + [Test] + public void CanStoreBase64EncodedImageInThumbnailProperty() + { + // Arrange + var imagePath = Path.Combine(TestDirectory, @"DynamoCoreTests\Graph\Workspaces\thumbnailTestImage.png"); + Assert.That(File.Exists(imagePath)); + + // Act + byte[] imageArray = System.IO.File.ReadAllBytes(imagePath); + string base64ImageRepresentation = Convert.ToBase64String(imageArray); + this.CurrentDynamoModel.CurrentWorkspace.Thumbnail = base64ImageRepresentation; + + // Assert + Assert.NotNull(base64ImageRepresentation); + Assert.AreEqual(this.CurrentDynamoModel.CurrentWorkspace.Thumbnail, base64ImageRepresentation); + } + + [Test] + public void WillNotStoreInvalidBase64StringInThumbnailProperty() + { + // Arrange + var invalidImagePath = "GenericString"; + + // Act + this.CurrentDynamoModel.CurrentWorkspace.Thumbnail = invalidImagePath; + + // Assert + Assert.IsNull(this.CurrentDynamoModel.CurrentWorkspace.Thumbnail); + } } } diff --git a/test/DynamoCoreTests/Graph/Workspaces/thumbnailTestImage.png b/test/DynamoCoreTests/Graph/Workspaces/thumbnailTestImage.png new file mode 100644 index 0000000000000000000000000000000000000000..6e4f005b3b766ed940ba03ca43120ed594e21e1a GIT binary patch literal 5501 zcmW+)2{=@38y>Sc7#w3PWgA;2yDZtwOk`&)iBb*8E~GNbHe)c9kQ!OO7&}Q+BwCEE z#FsVM(vZ?7gM>)`eE+$wbIx_W&;8!dd7t}v@9UhCL2|Jb7ThZcfk1@q?X2B-cRKH^ z0+76`3|6fW0+Fz`wdcNvyc_yKEL*u=*kd^*@vyH?Rg5g$uLxXpZ!P;i`{`xfG_$5~zZBX{kE@_KNSq`3 zhog3IuR0G}o(PvhTU-7M*X?dif#?zz5cj?q>LopHuBnZ<{{ zN`9Udk#3f^Jy(+7FtGDG&_n-;f_&{u?O`eA%6~w?4Uu+A=7sVnX!)5fWS|d&F4H?c zG&V_U&B0wr&3eSFxB0!D;lbe$4O*}0rc6jZ5hO&FfeQ8)&VS%6+s#xyQJRTnXH&;@ zHkP~AkAzXKWtpUR7JKveZ6!3;U4oVsiQ)rZhp9kbzoX>iup^3s>! ziSG7FKeJh(yw&@mSj(THXZY6fe4ny?Ut$Z{*TToaao4e%{B;ul9`SO6{txOTB1XIZp+J5Jp*^xFt7V8_ax4 z>04KMu(RAdV$Y}mj0MP)JexPj3`1eL!qk|#;39td5N`ZT>^FYGGY^#UqeGjU30>~e zJ0gqTloxCm(Hk=<;MFW+SG_3dCqC+PErt8*aSut_+=%jCmx5>=BoF+w& z!WpTI9kTu#vZ6bry^{CPapLduITvlppI(H56^B4QI(<>HlU3xB2ohN@vl^1S51cuv z=kd$s&~(qB-~8{p1t^y!#AJHI{s)duP8(+M`I>aINER0mTDnAFKJ#PD6)*32X4c6h6O{hSl`t!Udy2{U_Qp6^-O6rw4HCF8p;+>sR3 zbO=i)fhdF;OHYU`*@HM)WCn-EX7oREyb2}8VoajFx^?rsrwN}<)1nnsjKJx8GtmJ2 zQ|UIbJb6gM=Hv~;cA72L>!SQ=b&+2PSs@uxm5f`V{RAJ?3IA~g0I+quhz)z$| z??Y{V!aH`I@c%wPhz4}{@g%OHXB61Rdg*Z120nx3-n<^?meP0rxtJLxx>g_CSc1j$ z^0TvPX|8Z;=d9DJPF0YjS$AMN7Dc7ugRdzaY{>+28EZ(wMd}l8a0jFyJI+$L>7e@Sdj`nal7@dg0SeQSEqhq;DRfJp&z=>ljaYC<$3ShPHZknoaLq5)c?E$lYCC95oXYsm0_4LC7J7CwVc;1 zJlH!a2XyncclV*Dp3`ChIv10a5GQwi?F!%C@L=sBRWQTF_a5pP_W%eUAf4z4Vggkn zqI<4NrjVSQIYMz6siYeLeEp^x`i$ani%u3-*4z%VfJGZX2nD`B z(}u7kUi(t^Tdw)|5olO>o*|jsGea)3l)Wipc+xLrK|VqN{jilNOc@QO+AmMslgZ2( zUgPL*+EU6R<1d1?I+dY9G!lSN($^icgdkNWwahNqikTlk%%<4-CB7Hg1Mv}YY7P_S zVfd8#-zsb)HLK?B?<%B?Rk_(c$Re~YX}t`;4e{8npwAb71(^US&sm);C)vqL9Ui#}V<5*) zv#=NYy}T4epAzUhgp;1(<31OI#F_JpI65!TJ+Rzfk0f64^})cuctb^yF=7PmNTw+p zWEiOM7)%+OkqV(oZ(I_!Bu~U(gtj-xRACVssYZZSXt#t9&h(GAdPg?>rwJC@4JF__ z`EteNtL2bTmZe~*QpjdE*tUW}!awG0$A82RaqXvX^~>=SaNfFPar>_7#|YZFfR&=} z*v)j;9eb^dP?%~}LUjx_c+()A01A462Jx9E?^*EJOfzl%y3{^C*zgp90R$2VJd<%+;iYY32LPj4YE)f75Xu8Y<2~1LnMy4YX1|2B z!3U*yu)a%8E7E*x)EN5dt0W`hySp$vQ8QVOHx*9pQq$}xM&^b@q}RVfUJb=@PxGM! zX(RJ<*Se}rgq5B)EGi;zl7_OX=Lie*7hO}WC_MtkAnLSTm^2n}Rc(#vK+LcF)Dh!9H7oVeLBmb3Iz zTvCh@aw~{?%RwcJ<|n*ICs#UR!oUh)%r9{d@nJ;`6F&AM7};S$82j zEvO7p|FLPAD+5p>iKoKNKpE=HxMfYm>{Xj#3t_Fe#)=@kFBqwHlHshP0rVQtNwAG`$vzSsv%XIS1#JRXkrTI$LeAVgLvDKWFS+LIJ(fR^=I^#_ zG?`VMi2aPrAO257ie5xfU)|08@yxO?1U<0l`ly>s!Pplvq%&Y5uo&jQ2?ylwi?W!(hL zymMHizHru0CYvCExwl zha6$M{vmp=&FCi;dMS<(NT~PiewwNQ_M5~gIHN~tzu`SMzxZxo#dqh5bUIsK2h4DU5>uEpDNABvL& zFXafrn)5r{%oZxjGr|bfFaUB8_$p&8HLC44>T$_Y4*dCHZ7;P{S<(N)zRBED$;{pn zjOLSh?AiCbG?{Kz${`o4N99@@wjT*R+k}DVRl2?M4`6QXL5P$DKmuxA{GhDvwo4yd zjd^b;^PV((pNrn0tU%Z?bwe87K2(RAWq8LIyP4*?6LQ5hwV?v_*}0!~KxmzRstP?m zIqu*CQ$4~1e2>4FvI@+*v-I_ZFS-9al%M-Yw~cBSaxz<5p7(jPyMx~Gp4*Pyq1&P7`AyhoPC6JPU8IbZduKMI_{3DQWN_(cO+F8caU*Ocj+UzU8=M0Tqc zVoo*z=rincth!B|x1s2C^uCs$UVUc=yPHf?hr+R@(`KSm#)C#VUaDeHIIUBu9u#Fc zRA^%Du-1giGEIEwDE<1}ZCq4x#*Kl;`X9{7w;gTo->5rLd~fmjhSfpKQ5R>8{Xqh& zpB|Wp&nhTe)8h{yd21douo-dNb6j0DRaydGk-HcSI^*;Dzkh{_@Q^N!W zvGb}zGR~>AzbsV6HDj$}Y{w7UZZLAG%mD`NQp;3ji1NrL$R}~Xr_C?p9#GDp4j^wK zxs!R%ANd~mi_88e{ssU~j7`zk$9mK7cr2=#3-*boa+Wn#F3v${ZEV>PC2v|IenECF zkDtW30aitscKBU~@>r+&yH_ZMWC19QI+wTjrpPSwC@DHrd{Cqzxq~YZ?q^Q8g)I9o zrc)_mI0;M8Bj7s%t~;kEV6dDmb8nany#_*^6E_-i#l5a0c98ZLeM6<0A{HbWU#dk+ zs)!Xln*Gwa%tBx>?eKrYSF#lz4%W7YTvY-y{0sqUFq5c{cYDy+@mknf@TC?gw4Oa7 z-iI;3-p3DhsU_krrBA`q*lnqKR7kg{Ce@jN1)I)E8B|wYD62u9E0VtJUBW5g#lGh% z`*$Ye0kq{xz87OMq33Few+o39N2By5)Xq>mPT$Gg6sp?IENC2i29w^HI=$^~7rM1BM0w3Tg$exbw5@ zo160*i0IdQ$r{(b>V(DqR=awW?GsiS$-d-0Ck5pjWz|)c3-F4|y0;LucKEmNJpUT; za^<%3ntji4MNq25qWfJyS8PvJmvW(ar-DQy13?dpKfY{IgzQFSY?0|$x>lmAW;FoO*(=}9;lP* zKzm!1GO7w5KKsDsFR7~61wOE9 zix5<~R!p-ig46XVbyag7q2`JDX4Tqds@6{Wg>g4Wq&F3=DW!Ux$8xvg$;?t$)%;W5 zV}|Lf)*wUC;WXLL2BZ13hK*5-FMIKlEHJK7Tik^%t2cRP>gz0%gf4`gE;;v({x41- zjrICkl2u7QlOqmpPq0^SU+E>WAVqUil#7clJ93uxj@(J3hMYqBucmJWP_KnXxsO}1 zWAh;t%jH^C*~^9}Cho&)-$kTEZ6{xa7K#oV#Ham(Pym9ZKug|Ig^x3_%@3*!*EDiV zUdw$;5);W?7{HgD-435di{RWZ7oxL_RpI-KML^43`64?y>owLLcKGwq_@3^sG@Oxt6Vg1)m5 z&+qXg9&H+Y99MLM8yD*aBANC-X3?fJ literal 0 HcmV?d00001 From 8f2194e57e3e1a91efda1cf9a93b47e361776320 Mon Sep 17 00:00:00 2001 From: SHKnudsen Date: Mon, 22 Feb 2021 16:59:23 +0000 Subject: [PATCH 2/6] add graphDocumentationURL + serialise and deserialise Author --- .../Graph/Workspaces/SerializationConverters.cs | 14 ++++++++++++++ .../Graph/Workspaces/WorkspaceModel.cs | 17 ++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/DynamoCore/Graph/Workspaces/SerializationConverters.cs b/src/DynamoCore/Graph/Workspaces/SerializationConverters.cs index d2d2492d1a6..ac069b93c1e 100644 --- a/src/DynamoCore/Graph/Workspaces/SerializationConverters.cs +++ b/src/DynamoCore/Graph/Workspaces/SerializationConverters.cs @@ -652,6 +652,12 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist if (obj.TryGetValue(nameof(WorkspaceModel.Thumbnail), StringComparison.OrdinalIgnoreCase, out JToken thumbnail)) ws.Thumbnail = thumbnail.ToString(); + if (obj.TryGetValue(nameof(WorkspaceModel.GraphDocumentationURL), StringComparison.OrdinalIgnoreCase, out JToken helpLink)) + ws.GraphDocumentationURL = new Uri(helpLink.ToString()); + + if (obj.TryGetValue(nameof(WorkspaceModel.Author), StringComparison.OrdinalIgnoreCase, out JToken author)) + ws.Author = author.ToString(); + return ws; } @@ -778,6 +784,14 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s writer.WritePropertyName(nameof(WorkspaceModel.Thumbnail)); writer.WriteValue(ws.Thumbnail); + // GraphDocumentaionLink + writer.WritePropertyName(nameof(WorkspaceModel.GraphDocumentationURL)); + writer.WriteValue(ws.GraphDocumentationURL); + + // Graph Author + writer.WritePropertyName(nameof(WorkspaceModel.Author)); + writer.WriteValue(ws.Author); + if (engine != null) { // Bindings diff --git a/src/DynamoCore/Graph/Workspaces/WorkspaceModel.cs b/src/DynamoCore/Graph/Workspaces/WorkspaceModel.cs index 1e36e430f9e..dff1fbb9149 100644 --- a/src/DynamoCore/Graph/Workspaces/WorkspaceModel.cs +++ b/src/DynamoCore/Graph/Workspaces/WorkspaceModel.cs @@ -203,6 +203,8 @@ internal int CurrentPasteOffset private DateTime lastSaved; private string author = "None provided"; private string description; + private string thumbnail; + private Uri graphDocumentationURL; private bool hasUnsavedChanges; private bool isReadOnly; private readonly List nodes; @@ -724,7 +726,20 @@ public string Description } } - private string thumbnail; + /// + /// Link to documentation page for this workspace + /// + public Uri GraphDocumentationURL + { + get { return graphDocumentationURL; } + set + { + if (graphDocumentationURL == value) + return; + + graphDocumentationURL = value; } + } + /// /// Workspace thumbnail as Base64 string. From 73049cabbeab67099d75f15c4b4954f31559946e Mon Sep 17 00:00:00 2001 From: SHKnudsen Date: Mon, 22 Feb 2021 17:05:21 +0000 Subject: [PATCH 3/6] Update WorkspaceModel.cs --- src/DynamoCore/Graph/Workspaces/WorkspaceModel.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/DynamoCore/Graph/Workspaces/WorkspaceModel.cs b/src/DynamoCore/Graph/Workspaces/WorkspaceModel.cs index dff1fbb9149..bf370b8eca3 100644 --- a/src/DynamoCore/Graph/Workspaces/WorkspaceModel.cs +++ b/src/DynamoCore/Graph/Workspaces/WorkspaceModel.cs @@ -737,7 +737,9 @@ public Uri GraphDocumentationURL if (graphDocumentationURL == value) return; - graphDocumentationURL = value; } + graphDocumentationURL = value; + RaisePropertyChanged(nameof(GraphDocumentationURL)); + } } @@ -755,6 +757,7 @@ public string Thumbnail // if value is not a valid Base64 string this will throw, and we return null. byte[] data = Convert.FromBase64String(value); thumbnail = value; + RaisePropertyChanged(nameof(Thumbnail)); } catch { From ed38bd079306b33784d110050dbcd265dd6d3621 Mon Sep 17 00:00:00 2001 From: SHKnudsen Date: Tue, 23 Feb 2021 10:22:48 +0000 Subject: [PATCH 4/6] handle empty URIs --- src/DynamoCore/Graph/Workspaces/SerializationConverters.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/DynamoCore/Graph/Workspaces/SerializationConverters.cs b/src/DynamoCore/Graph/Workspaces/SerializationConverters.cs index ac069b93c1e..8e8e9b49f5d 100644 --- a/src/DynamoCore/Graph/Workspaces/SerializationConverters.cs +++ b/src/DynamoCore/Graph/Workspaces/SerializationConverters.cs @@ -653,7 +653,11 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist ws.Thumbnail = thumbnail.ToString(); if (obj.TryGetValue(nameof(WorkspaceModel.GraphDocumentationURL), StringComparison.OrdinalIgnoreCase, out JToken helpLink)) - ws.GraphDocumentationURL = new Uri(helpLink.ToString()); + { + if (Uri.TryCreate(helpLink.ToString(), UriKind.Absolute, out Uri uri)) + ws.GraphDocumentationURL = uri; + } + if (obj.TryGetValue(nameof(WorkspaceModel.Author), StringComparison.OrdinalIgnoreCase, out JToken author)) ws.Author = author.ToString(); From 5cc17c4acbf6f71ed2246f59689d0cfec26708b7 Mon Sep 17 00:00:00 2001 From: SHKnudsen Date: Wed, 17 Mar 2021 16:29:22 +0000 Subject: [PATCH 5/6] Update 2080_JSONTESTCRASH undo_redo.dyn --- .../dummy_node/2080_JSONTESTCRASH undo_redo.dyn | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/test/core/dummy_node/2080_JSONTESTCRASH undo_redo.dyn b/test/core/dummy_node/2080_JSONTESTCRASH undo_redo.dyn index d015940da0a..fe13685ae1c 100644 --- a/test/core/dummy_node/2080_JSONTESTCRASH undo_redo.dyn +++ b/test/core/dummy_node/2080_JSONTESTCRASH undo_redo.dyn @@ -53,13 +53,16 @@ "Connectors": [], "Dependencies": [], "NodeLibraryDependencies": [], + "Thumbnail": "", + "GraphDocumentationURL": null, + "Author": "None provided", "Bindings": [], "View": { "Dynamo": { "ScaleFactor": 1.0, "HasRunWithoutCrash": true, "IsVisibleInDynamoLibrary": true, - "Version": "2.3.0.5184", + "Version": "2.11.0.4415", "RunType": "Automatic", "RunPeriod": "1000" }, @@ -77,21 +80,21 @@ }, "NodeViews": [ { - "ShowGeometry": true, - "Name": "Code Block", "Id": "158f8f25ddb746c88323ae262e87611e", "IsSetAsInput": false, "IsSetAsOutput": false, + "Name": "Code Block", + "ShowGeometry": true, "Excluded": false, "X": 179.8, "Y": 160.39999999999992 }, { - "ShowGeometry": true, - "Name": "Code Block", "Id": "6cbd0760736f4235a03b38fb359e9957", "IsSetAsInput": false, "IsSetAsOutput": false, + "Name": "Code Block", + "ShowGeometry": true, "Excluded": false, "X": 76.8, "Y": 162.4 From 6807f8f8eacd83ab7770b0cd42a714b59ea1c45a Mon Sep 17 00:00:00 2001 From: SHKnudsen Date: Thu, 18 Mar 2021 16:23:10 +0000 Subject: [PATCH 6/6] move thumbnail and help link to HomeWorkspaceMode --- .../Graph/Workspaces/HomeWorkspaceModel.cs | 42 +++++++++++++++++ .../Workspaces/SerializationConverters.cs | 38 ++++++++------- .../Graph/Workspaces/WorkspaceModel.cs | 46 +------------------ .../Graph/Workspaces/WorkspaceModelTests.cs | 13 ++++-- 4 files changed, 75 insertions(+), 64 deletions(-) diff --git a/src/DynamoCore/Graph/Workspaces/HomeWorkspaceModel.cs b/src/DynamoCore/Graph/Workspaces/HomeWorkspaceModel.cs index 6fd3d6ae87e..8858121b6c7 100644 --- a/src/DynamoCore/Graph/Workspaces/HomeWorkspaceModel.cs +++ b/src/DynamoCore/Graph/Workspaces/HomeWorkspaceModel.cs @@ -27,6 +27,8 @@ public class HomeWorkspaceModel : WorkspaceModel { #region Class Data Members and Properties + private string thumbnail; + private Uri graphDocumentationURL; private readonly DynamoScheduler scheduler; private PulseMaker pulseMaker; private readonly bool verboseLogging; @@ -89,6 +91,46 @@ public class HomeWorkspaceModel : WorkspaceModel [JsonIgnore] public long EvaluationCount { get; private set; } + /// + /// Link to documentation page for this workspace + /// + public Uri GraphDocumentationURL + { + get { return graphDocumentationURL; } + set + { + if (graphDocumentationURL == value) + return; + + graphDocumentationURL = value; + RaisePropertyChanged(nameof(GraphDocumentationURL)); + } + } + + + /// + /// Workspace thumbnail as Base64 string. + /// Returns null if provide value is not Base64 encoded. + /// + public string Thumbnail + { + get { return thumbnail; } + set + { + try + { + // if value is not a valid Base64 string this will throw, and we return null. + byte[] data = Convert.FromBase64String(value); + thumbnail = value; + RaisePropertyChanged(nameof(Thumbnail)); + } + catch + { + return; + } + } + } + /// /// In near future, the file loading mechanism will be completely moved /// into WorkspaceModel, that's the time we removed this property setter below. diff --git a/src/DynamoCore/Graph/Workspaces/SerializationConverters.cs b/src/DynamoCore/Graph/Workspaces/SerializationConverters.cs index 8e8e9b49f5d..3416cc9e2bf 100644 --- a/src/DynamoCore/Graph/Workspaces/SerializationConverters.cs +++ b/src/DynamoCore/Graph/Workspaces/SerializationConverters.cs @@ -641,23 +641,25 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist } else { - ws = new HomeWorkspaceModel(guid, engine, scheduler, factory, + var homeWorkspace = new HomeWorkspaceModel(guid, engine, scheduler, factory, loadedTraceData, nodes, notes, annotations, Enumerable.Empty(), elementResolver, info, verboseLogging, isTestMode); + + if (obj.TryGetValue(nameof(HomeWorkspaceModel.Thumbnail), StringComparison.OrdinalIgnoreCase, out JToken thumbnail)) + homeWorkspace.Thumbnail = thumbnail.ToString(); + + if (obj.TryGetValue(nameof(HomeWorkspaceModel.GraphDocumentationURL), StringComparison.OrdinalIgnoreCase, out JToken helpLink)) + { + if (Uri.TryCreate(helpLink.ToString(), UriKind.Absolute, out Uri uri)) + homeWorkspace.GraphDocumentationURL = uri; + } + + ws = homeWorkspace; } ws.NodeLibraryDependencies = nodeLibraryDependencies.ToList(); ws.ExtensionData = GetExtensionData(serializer, obj); - if (obj.TryGetValue(nameof(WorkspaceModel.Thumbnail), StringComparison.OrdinalIgnoreCase, out JToken thumbnail)) - ws.Thumbnail = thumbnail.ToString(); - - if (obj.TryGetValue(nameof(WorkspaceModel.GraphDocumentationURL), StringComparison.OrdinalIgnoreCase, out JToken helpLink)) - { - if (Uri.TryCreate(helpLink.ToString(), UriKind.Absolute, out Uri uri)) - ws.GraphDocumentationURL = uri; - } - if (obj.TryGetValue(nameof(WorkspaceModel.Author), StringComparison.OrdinalIgnoreCase, out JToken author)) ws.Author = author.ToString(); @@ -784,13 +786,17 @@ public override void WriteJson(JsonWriter writer, object value, JsonSerializer s writer.WritePropertyName(WorkspaceReadConverter.EXTENSION_WORKSPACE_DATA); serializer.Serialize(writer, ws.ExtensionData); - // Thumbnail - writer.WritePropertyName(nameof(WorkspaceModel.Thumbnail)); - writer.WriteValue(ws.Thumbnail); + + if (!isCustomNode && ws is HomeWorkspaceModel hws) + { + // Thumbnail + writer.WritePropertyName(nameof(HomeWorkspaceModel.Thumbnail)); + writer.WriteValue(hws.Thumbnail); - // GraphDocumentaionLink - writer.WritePropertyName(nameof(WorkspaceModel.GraphDocumentationURL)); - writer.WriteValue(ws.GraphDocumentationURL); + // GraphDocumentaionLink + writer.WritePropertyName(nameof(HomeWorkspaceModel.GraphDocumentationURL)); + writer.WriteValue(hws.GraphDocumentationURL); + } // Graph Author writer.WritePropertyName(nameof(WorkspaceModel.Author)); diff --git a/src/DynamoCore/Graph/Workspaces/WorkspaceModel.cs b/src/DynamoCore/Graph/Workspaces/WorkspaceModel.cs index bf370b8eca3..040b982c9da 100644 --- a/src/DynamoCore/Graph/Workspaces/WorkspaceModel.cs +++ b/src/DynamoCore/Graph/Workspaces/WorkspaceModel.cs @@ -203,8 +203,6 @@ internal int CurrentPasteOffset private DateTime lastSaved; private string author = "None provided"; private string description; - private string thumbnail; - private Uri graphDocumentationURL; private bool hasUnsavedChanges; private bool isReadOnly; private readonly List nodes; @@ -698,7 +696,7 @@ internal List NodeLibraryDependencies } private Dictionary nodePackageDictionary = new Dictionary(); - + /// /// An author of the workspace @@ -709,7 +707,7 @@ public string Author set { author = value; - RaisePropertyChanged("Author"); + RaisePropertyChanged(nameof(Author)); } } @@ -726,46 +724,6 @@ public string Description } } - /// - /// Link to documentation page for this workspace - /// - public Uri GraphDocumentationURL - { - get { return graphDocumentationURL; } - set - { - if (graphDocumentationURL == value) - return; - - graphDocumentationURL = value; - RaisePropertyChanged(nameof(GraphDocumentationURL)); - } - } - - - /// - /// Workspace thumbnail as Base64 string. - /// Returns null if provide value is not Base64 encoded. - /// - public string Thumbnail - { - get { return thumbnail; } - set - { - try - { - // if value is not a valid Base64 string this will throw, and we return null. - byte[] data = Convert.FromBase64String(value); - thumbnail = value; - RaisePropertyChanged(nameof(Thumbnail)); - } - catch - { - return; - } - } - } - /// /// List of user defined data from extensions and view extensions stored in the graph /// diff --git a/test/DynamoCoreTests/Graph/Workspaces/WorkspaceModelTests.cs b/test/DynamoCoreTests/Graph/Workspaces/WorkspaceModelTests.cs index a94dd825e39..a4e998de46f 100644 --- a/test/DynamoCoreTests/Graph/Workspaces/WorkspaceModelTests.cs +++ b/test/DynamoCoreTests/Graph/Workspaces/WorkspaceModelTests.cs @@ -295,11 +295,14 @@ public void CanStoreBase64EncodedImageInThumbnailProperty() // Act byte[] imageArray = System.IO.File.ReadAllBytes(imagePath); string base64ImageRepresentation = Convert.ToBase64String(imageArray); - this.CurrentDynamoModel.CurrentWorkspace.Thumbnail = base64ImageRepresentation; + if (!(this.CurrentDynamoModel.CurrentWorkspace is HomeWorkspaceModel hws)) + throw new Exception("current workspace is not a HomeWorkspaceModel"); + + hws.Thumbnail = base64ImageRepresentation; // Assert Assert.NotNull(base64ImageRepresentation); - Assert.AreEqual(this.CurrentDynamoModel.CurrentWorkspace.Thumbnail, base64ImageRepresentation); + Assert.AreEqual(hws.Thumbnail, base64ImageRepresentation); } [Test] @@ -309,10 +312,12 @@ public void WillNotStoreInvalidBase64StringInThumbnailProperty() var invalidImagePath = "GenericString"; // Act - this.CurrentDynamoModel.CurrentWorkspace.Thumbnail = invalidImagePath; + if (!(this.CurrentDynamoModel.CurrentWorkspace is HomeWorkspaceModel hws)) + throw new Exception("current workspace is not a HomeWorkspaceModel"); + hws.Thumbnail = invalidImagePath; // Assert - Assert.IsNull(this.CurrentDynamoModel.CurrentWorkspace.Thumbnail); + Assert.IsNull(hws.Thumbnail); } } }