@@ -90,31 +90,6 @@ scopedTrackedDynamic[ expr_, args___ ] :=
9090
9191scopedTrackedDynamic // endDefinition ;
9292
93- (* ::**************************************************************************************************************:: *)
94- (* ::Subsection::Closed:: *)
95- (*currentTabPageDynamic*)
96- currentTabPageDynamic // beginDefinition ;
97- currentTabPageDynamic // Attributes = { HoldFirst };
98-
99- currentTabPageDynamic [ scope_ ] := expandScope @ Dynamic [
100- Replace [ CurrentChatSettings [ scope , "CurrentPreferencesTab" ], $$unspecified -> "Services" ],
101- (CurrentChatSettings [ scope , "CurrentPreferencesTab" ] = #1 ) &
102- ];
103-
104- currentTabPageDynamic // endDefinition ;
105-
106- (* ::**************************************************************************************************************:: *)
107- (* ::Subsection::Closed:: *)
108- (*currentTabPage*)
109- currentTabPage // beginDefinition ;
110-
111- currentTabPage [ scope_ ] := Replace [
112- CurrentChatSettings [ scope , "CurrentPreferencesTab" ],
113- $$unspecified -> "Services"
114- ];
115-
116- currentTabPage // endDefinition ;
117-
11893(* ::**************************************************************************************************************:: *)
11994(* ::Section::Closed:: *)
12095(*Main*)
@@ -134,35 +109,42 @@ createPreferencesContent[ ] := Enclose[
134109 "Tabs"
135110 ];
136111
137- (* Create a TabView for the preferences content, with the tab state stored in the FE's private options: *)
138- tabView = TabView [
139- tabs ,
140- currentTabPageDynamic @ $preferencesScope ,
141- Background -> None ,
142- FrameMargins -> { { 2 , 2 }, { 2 , 3 } },
143- ImageMargins -> { { 10 , 10 }, { 2 , 2 } },
144- ImageSize -> { $preferencesWidth , Automatic },
145- LabelStyle -> "feTabView" (* Defined in the SystemDialog stylesheet: *)
146- ];
112+ DynamicModule [ { tab },
113+
114+ (* Create a TabView for the preferences content, with the tab state stored in the FE's private options: *)
115+ tabView = TabView [
116+ tabs ,
117+ Dynamic @ tab ,
118+ Background -> None ,
119+ FrameMargins -> { { 2 , 2 }, { 2 , 3 } },
120+ ImageMargins -> { { 10 , 10 }, { 2 , 2 } },
121+ ImageSize -> { $preferencesWidth , Automatic },
122+ LabelStyle -> "feTabView" (* Defined in the SystemDialog stylesheet: *)
123+ ];
147124
148- (* Create a reset button that will reset preferences to default settings: *)
149- reset = Pane [ $resetButton , ImageMargins -> { { 20 , 0 }, { 0 , 10 } }, ImageSize -> $preferencesWidth ];
125+ (* Create a reset button that will reset preferences to default settings: *)
126+ reset = Pane [ resetButton [ Dynamic @ tab ], ImageMargins -> { { 20 , 0 }, { 0 , 10 } }, ImageSize -> $preferencesWidth ];
127+
128+ (* Arrange the TabView and reset button in a Grid layout with vertical spacers: *)
129+ makeScrollableInCloud @ Grid [
130+ {
131+ $verticalSpacer ,
132+ { tabView , "" },
133+ $verticalSpacer ,
134+ { reset , SpanFromLeft },
135+ $verticalSpacer
136+ },
137+ Alignment -> Left ,
138+ BaseStyle -> "defaultGrid" , (* Defined in the SystemDialog stylesheet *)
139+ AutoDelete -> False ,
140+ FrameStyle -> { AbsoluteThickness [ 1 ], color @ "PreferencesContentFrame" },
141+ Dividers -> { False , { 4 -> True } },
142+ Spacings -> { 0 , 0.7 }
143+ ],
144+
145+ Initialization :> (tab = Replace [ CurrentChatSettings [ $preferencesScope , "CurrentPreferencesTab" ], $$unspecified -> "Services" ]),
146+ Deinitialization :> (CurrentChatSettings [ $preferencesScope , "CurrentPreferencesTab" ] = tab )
150147
151- (* Arrange the TabView and reset button in a Grid layout with vertical spacers: *)
152- makeScrollableInCloud @ Grid [
153- {
154- $verticalSpacer ,
155- { tabView , "" },
156- $verticalSpacer ,
157- { reset , SpanFromLeft },
158- $verticalSpacer
159- },
160- Alignment -> Left ,
161- BaseStyle -> "defaultGrid" , (* Defined in the SystemDialog stylesheet *)
162- AutoDelete -> False ,
163- FrameStyle -> { AbsoluteThickness [ 1 ], color @ "PreferencesContentFrame" },
164- Dividers -> { False , { 4 -> True } },
165- Spacings -> { 0 , 0.7 }
166148 ]
167149 ],
168150 throwInternalFailure
@@ -510,10 +492,10 @@ makeServiceSelector[
510492 Dynamic [ state_ ],
511493 services_
512494] :=
513- DynamicModule [ { displayValue = expandScope @ extractServiceName @ CurrentChatSettings [ $preferencesScope , "Model" ] },
495+ DynamicModule [ { changedValueQ = False , displayValue = expandScope @ extractServiceName @ CurrentChatSettings [ $preferencesScope , "Model" ] },
514496 DynamicWrapper [
515497 PopupMenu [
516- Dynamic @ displayValue ,
498+ Dynamic [ displayValue , Function [ If [ displayValue =!= # , displayValue = # ; changedValueQ = True ] ] ] ,
517499 (* ensure LLMKit is first in the popup followed by a delimiter *)
518500 Replace [
519501 KeyValueMap [
@@ -522,11 +504,11 @@ makeServiceSelector[
522504 ],
523505 { a___ , b :("LLMKit" -> _ ), c___ } :> { b , Delimiter , a , c } ]
524506 ]
525- ,
526- serviceSelectCallback [ Dynamic @ service , Dynamic @ model , Dynamic @ modelNameSelector , Dynamic @ state ] @ displayValue
507+ , (* we only want this asynchronous evaluation to fire if we've changed from the initial value of the service *)
508+ If [ changedValueQ , changedValueQ = False ; serviceSelectCallback [ Dynamic @ service , Dynamic @ model , Dynamic @ modelNameSelector , Dynamic @ state ] @ displayValue ]
527509 ,
528510 SynchronousUpdating -> False ,
529- TrackedSymbols :> { displayValue }
511+ TrackedSymbols :> { changedValueQ }
530512 ]
531513 ];
532514
@@ -642,24 +624,25 @@ makeModelNameSelector[
642624
643625 DynamicModule [
644626 {
627+ changedValueQ = False ,
645628 displayValue = expandScope @ Replace [
646629 extractModelName @ CurrentChatSettings [ $preferencesScope , "Model" ],
647630 Except [ _ String ] :> (CurrentChatSettings [ $preferencesScope , "Model" ] = fallback )
648631 ]
649632 },
650633 DynamicWrapper [
651634 PopupMenu [
652- Dynamic @ displayValue ,
635+ Dynamic [ displayValue , Function [ If [ displayValue =!= # , displayValue = # ; changedValueQ = True ] ] ] ,
653636 Block [ { $noIcons = TrueQ @ $cloudNotebooks },
654637 Map [ popupValue [ # [ "Name" ], # [ "DisplayName" ], # [ "Icon" ] ] & , models ]
655638 ],
656639 ImageSize -> Automatic
657640 ]
658- ,
659- modelSelectCallback [ Dynamic @ service , Dynamic @ model ] @ displayValue
641+ , (* we only want this asynchronous evaluation to fire if we've changed from the initial value of the model name *)
642+ If [ changedValueQ , changedValueQ = False ; modelSelectCallback [ Dynamic @ service , Dynamic @ model ] @ displayValue ]
660643 ,
661644 SynchronousUpdating -> False ,
662- TrackedSymbols :> { displayValue }
645+ TrackedSymbols :> { changedValueQ }
663646 ]
664647 ]
665648 ],
@@ -1925,8 +1908,8 @@ $trashBin := Mouseover[
19251908
19261909(* ::**************************************************************************************************************:: *)
19271910(* ::Subsection::Closed:: *)
1928- (*$ resetButton*)
1929- $ resetButton :=
1911+ (*resetButton*)
1912+ resetButton [ Dynamic [ tab_ ] ] :=
19301913 Module [ { icon , label },
19311914 icon = Style [
19321915 Dynamic [ RawBoxes @ FEPrivate ` FrontEndResource [ "FEBitmaps" , "SyntaxColorResetIcon" ][ # ] ]& [
@@ -1945,7 +1928,7 @@ $resetButton :=
19451928 label ,
19461929
19471930 Needs [ "Wolfram`Chatbook`" -> None ];
1948- resetChatPreferences @ currentTabPage @ $preferencesScope
1931+ resetChatPreferences @ Replace [ tab , CurrentChatSettings [ $preferencesScope , "CurrentPreferencesTab" ], $$unspecified -> "Services" ]
19491932 ,
19501933 BaseStyle -> {
19511934 FontFamily -> Dynamic @ FrontEnd ` CurrentValue [ "ControlsFontFamily" ],
0 commit comments