Skip to content

Commit c87a0dd

Browse files
authored
Merge pull request #31 from CombineCommunity/improve/ui-systems
Unify the UISystems
2 parents 00d70f4 + b3809f8 commit c87a0dd

32 files changed

+1152
-640
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
**vx.y.z - Vader**:
2+
3+
- UISystem: unify the UISystem concept for RawState and ViewState
4+
15
**v0.1.0 - Sidious:**
26

37
- Transitions, Transition, Feedacks, Feedback and System initial functional version

Examples/Examples.xcodeproj/project.pbxproj

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,15 @@
4141
747182A825AE7B0E0098E83E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 747182A725AE7B0E0098E83E /* Assets.xcassets */; };
4242
747182AB25AE7B0E0098E83E /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 747182AA25AE7B0E0098E83E /* Preview Assets.xcassets */; };
4343
747182B525AE7FB30098E83E /* Feedbacks in Frameworks */ = {isa = PBXBuildFile; productRef = 747182B425AE7FB30098E83E /* Feedbacks */; };
44-
747182BA25AE80360098E83E /* CounterHomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 747182B925AE80360098E83E /* CounterHomeView.swift */; };
45-
747182C225AE80DC0098E83E /* Events.swift in Sources */ = {isa = PBXBuildFile; fileRef = 747182C125AE80DC0098E83E /* Events.swift */; };
46-
747182C625AE81180098E83E /* States.swift in Sources */ = {isa = PBXBuildFile; fileRef = 747182C525AE81180098E83E /* States.swift */; };
44+
747182BA25AE80360098E83E /* CounterApp+RootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 747182B925AE80360098E83E /* CounterApp+RootView.swift */; };
45+
747182C225AE80DC0098E83E /* CounterApp+Events.swift in Sources */ = {isa = PBXBuildFile; fileRef = 747182C125AE80DC0098E83E /* CounterApp+Events.swift */; };
46+
747182C625AE81180098E83E /* CounterApp+States.swift in Sources */ = {isa = PBXBuildFile; fileRef = 747182C525AE81180098E83E /* CounterApp+States.swift */; };
4747
747182C925AE82640098E83E /* CounterApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 747182C825AE82640098E83E /* CounterApp.swift */; };
48-
747182CC25AE830E0098E83E /* Transitions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 747182CB25AE830E0098E83E /* Transitions.swift */; };
49-
747182CF25AE85B40098E83E /* SideEffects.swift in Sources */ = {isa = PBXBuildFile; fileRef = 747182CE25AE85B40098E83E /* SideEffects.swift */; };
50-
747182D425AE878D0098E83E /* System.swift in Sources */ = {isa = PBXBuildFile; fileRef = 747182D325AE878D0098E83E /* System.swift */; };
51-
747182DC25AE8B260098E83E /* ViewState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 747182DB25AE8B250098E83E /* ViewState.swift */; };
48+
747182CC25AE830E0098E83E /* CounterApp+Transitions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 747182CB25AE830E0098E83E /* CounterApp+Transitions.swift */; };
49+
747182CF25AE85B40098E83E /* CounterApp+SideEffects.swift in Sources */ = {isa = PBXBuildFile; fileRef = 747182CE25AE85B40098E83E /* CounterApp+SideEffects.swift */; };
50+
747182D425AE878D0098E83E /* CounterApp+System.swift in Sources */ = {isa = PBXBuildFile; fileRef = 747182D325AE878D0098E83E /* CounterApp+System.swift */; };
51+
749D95FC25CF4ED200795E04 /* GifDetail+Dependencies.swift in Sources */ = {isa = PBXBuildFile; fileRef = 749D95FB25CF4ED200795E04 /* GifDetail+Dependencies.swift */; };
52+
749D960025CF50EF00795E04 /* GifList+Dependencies.swift in Sources */ = {isa = PBXBuildFile; fileRef = 749D95FF25CF50EF00795E04 /* GifList+Dependencies.swift */; };
5253
74EAB46C25B7BF0A003283E4 /* GifDetail+ViewState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74EAB46B25B7BF0A003283E4 /* GifDetail+ViewState.swift */; };
5354
/* End PBXBuildFile section */
5455

@@ -88,14 +89,15 @@
8889
747182A725AE7B0E0098E83E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
8990
747182AA25AE7B0E0098E83E /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
9091
747182AC25AE7B0E0098E83E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
91-
747182B925AE80360098E83E /* CounterHomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CounterHomeView.swift; sourceTree = "<group>"; };
92-
747182C125AE80DC0098E83E /* Events.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Events.swift; sourceTree = "<group>"; };
93-
747182C525AE81180098E83E /* States.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = States.swift; sourceTree = "<group>"; };
92+
747182B925AE80360098E83E /* CounterApp+RootView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CounterApp+RootView.swift"; sourceTree = "<group>"; };
93+
747182C125AE80DC0098E83E /* CounterApp+Events.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CounterApp+Events.swift"; sourceTree = "<group>"; };
94+
747182C525AE81180098E83E /* CounterApp+States.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CounterApp+States.swift"; sourceTree = "<group>"; };
9495
747182C825AE82640098E83E /* CounterApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CounterApp.swift; sourceTree = "<group>"; };
95-
747182CB25AE830E0098E83E /* Transitions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Transitions.swift; sourceTree = "<group>"; };
96-
747182CE25AE85B40098E83E /* SideEffects.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SideEffects.swift; sourceTree = "<group>"; };
97-
747182D325AE878D0098E83E /* System.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = System.swift; sourceTree = "<group>"; };
98-
747182DB25AE8B250098E83E /* ViewState.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewState.swift; sourceTree = "<group>"; };
96+
747182CB25AE830E0098E83E /* CounterApp+Transitions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CounterApp+Transitions.swift"; sourceTree = "<group>"; };
97+
747182CE25AE85B40098E83E /* CounterApp+SideEffects.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CounterApp+SideEffects.swift"; sourceTree = "<group>"; };
98+
747182D325AE878D0098E83E /* CounterApp+System.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CounterApp+System.swift"; sourceTree = "<group>"; };
99+
749D95FB25CF4ED200795E04 /* GifDetail+Dependencies.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "GifDetail+Dependencies.swift"; sourceTree = "<group>"; };
100+
749D95FF25CF50EF00795E04 /* GifList+Dependencies.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "GifList+Dependencies.swift"; sourceTree = "<group>"; };
99101
74EAB46B25B7BF0A003283E4 /* GifDetail+ViewState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "GifDetail+ViewState.swift"; sourceTree = "<group>"; };
100102
/* End PBXFileReference section */
101103

@@ -145,6 +147,7 @@
145147
742FEE2225B388B000575CB2 /* System */ = {
146148
isa = PBXGroup;
147149
children = (
150+
749D95FF25CF50EF00795E04 /* GifList+Dependencies.swift */,
148151
742FEE3025B38F5300575CB2 /* GifList+Events.swift */,
149152
742FEE3825B3978600575CB2 /* GifList+SideEffects.swift */,
150153
742FEE2725B38B1A00575CB2 /* GifList+States.swift */,
@@ -226,6 +229,7 @@
226229
742FEE7025B4F64000575CB2 /* System */ = {
227230
isa = PBXGroup;
228231
children = (
232+
749D95FB25CF4ED200795E04 /* GifDetail+Dependencies.swift */,
229233
742FEE7925B508FC00575CB2 /* GifDetail+Events.swift */,
230234
742FEE8625B50CCA00575CB2 /* GifDetail+SideEffects.swift */,
231235
742FEE7625B506E700575CB2 /* GifDetail+States.swift */,
@@ -295,20 +299,19 @@
295299
747182BD25AE80950098E83E /* System */ = {
296300
isa = PBXGroup;
297301
children = (
298-
747182C125AE80DC0098E83E /* Events.swift */,
299-
747182CE25AE85B40098E83E /* SideEffects.swift */,
300-
747182C525AE81180098E83E /* States.swift */,
301-
747182D325AE878D0098E83E /* System.swift */,
302-
747182CB25AE830E0098E83E /* Transitions.swift */,
302+
747182C125AE80DC0098E83E /* CounterApp+Events.swift */,
303+
747182CE25AE85B40098E83E /* CounterApp+SideEffects.swift */,
304+
747182C525AE81180098E83E /* CounterApp+States.swift */,
305+
747182D325AE878D0098E83E /* CounterApp+System.swift */,
306+
747182CB25AE830E0098E83E /* CounterApp+Transitions.swift */,
303307
);
304308
path = System;
305309
sourceTree = "<group>";
306310
};
307311
747182BE25AE809E0098E83E /* Views */ = {
308312
isa = PBXGroup;
309313
children = (
310-
747182B925AE80360098E83E /* CounterHomeView.swift */,
311-
747182DB25AE8B250098E83E /* ViewState.swift */,
314+
747182B925AE80360098E83E /* CounterApp+RootView.swift */,
312315
);
313316
path = Views;
314317
sourceTree = "<group>";
@@ -390,28 +393,29 @@
390393
files = (
391394
747182C925AE82640098E83E /* CounterApp.swift in Sources */,
392395
742FEE3125B38F5300575CB2 /* GifList+Events.swift in Sources */,
393-
747182C625AE81180098E83E /* States.swift in Sources */,
396+
747182C625AE81180098E83E /* CounterApp+States.swift in Sources */,
394397
742FEE8725B50CCA00575CB2 /* GifDetail+SideEffects.swift in Sources */,
395398
742FEE9725B52D2D00575CB2 /* GifDetail+RootView.swift in Sources */,
396399
742FEE2425B388DA00575CB2 /* GifList.swift in Sources */,
397400
742FEE4725B3AC3600575CB2 /* HTTPService.swift in Sources */,
398-
747182DC25AE8B260098E83E /* ViewState.swift in Sources */,
399401
742FEE2825B38B1A00575CB2 /* GifList+States.swift in Sources */,
400402
742FEE5725B3CB6000575CB2 /* Pagination.swift in Sources */,
401403
742FEE7E25B50A7C00575CB2 /* GifDetail+Transitions.swift in Sources */,
404+
749D95FC25CF4ED200795E04 /* GifDetail+Dependencies.swift in Sources */,
402405
742FEE6325B3CED500575CB2 /* GifList+RowView.swift in Sources */,
403406
742FEE3925B3978600575CB2 /* GifList+SideEffects.swift in Sources */,
404-
747182CF25AE85B40098E83E /* SideEffects.swift in Sources */,
407+
747182CF25AE85B40098E83E /* CounterApp+SideEffects.swift in Sources */,
405408
742FEE9225B526EB00575CB2 /* GifDetail+System.swift in Sources */,
406-
747182C225AE80DC0098E83E /* Events.swift in Sources */,
409+
747182C225AE80DC0098E83E /* CounterApp+Events.swift in Sources */,
410+
749D960025CF50EF00795E04 /* GifList+Dependencies.swift in Sources */,
407411
742FEE2E25B38EEE00575CB2 /* GifOverview.swift in Sources */,
408-
747182BA25AE80360098E83E /* CounterHomeView.swift in Sources */,
412+
747182BA25AE80360098E83E /* CounterApp+RootView.swift in Sources */,
409413
742FEE6025B3CC8800575CB2 /* GifList+ViewState.swift in Sources */,
410414
742FEE6925B3D02500575CB2 /* ActivityIndicatorView.swift in Sources */,
411415
742FEE7A25B508FC00575CB2 /* GifDetail+Events.swift in Sources */,
412416
742FEE5C25B3CC7200575CB2 /* GifList+RootView.swift in Sources */,
413417
742FEE5025B3B42D00575CB2 /* GifListRequestParameter.swift in Sources */,
414-
747182CC25AE830E0098E83E /* Transitions.swift in Sources */,
418+
747182CC25AE830E0098E83E /* CounterApp+Transitions.swift in Sources */,
415419
742FEE6C25B3D58300575CB2 /* Encodable+Dictionary.swift in Sources */,
416420
742FEE7325B4F65300575CB2 /* GifDetail.swift in Sources */,
417421
742FEE8D25B5260E00575CB2 /* GifDetailResponse.swift in Sources */,
@@ -421,7 +425,7 @@
421425
742FEE4325B3AA2500575CB2 /* StorageService.swift in Sources */,
422426
742FEE8225B50A9000575CB2 /* Images.swift in Sources */,
423427
747182A625AE7B0B0098E83E /* ContentView.swift in Sources */,
424-
747182D425AE878D0098E83E /* System.swift in Sources */,
428+
747182D425AE878D0098E83E /* CounterApp+System.swift in Sources */,
425429
742FEE5825B3CB6000575CB2 /* Meta.swift in Sources */,
426430
742FEE8325B50A9000575CB2 /* Gif.swift in Sources */,
427431
742FEE4B25B3B3A200575CB2 /* GifList+System.swift in Sources */,
@@ -622,8 +626,8 @@
622626
isa = XCRemoteSwiftPackageReference;
623627
repositoryURL = "git@github.com:twittemb/Feedbacks.git";
624628
requirement = {
625-
kind = exactVersion;
626-
version = 0.1.0;
629+
kind = revision;
630+
revision = 997f6fbad8e51401a027bdb60bfd4fbc3b15f553;
627631
};
628632
};
629633
/* End XCRemoteSwiftPackageReference section */

Examples/Examples.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Examples/Examples/ContentView.swift

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,19 @@ struct ContentView: View {
1212
NavigationView {
1313
List {
1414
NavigationLink("Counter Application",
15-
destination: CounterHomeView(
16-
system: CounterApp.System.counter
17-
.uiSystem(viewStateFactory: CounterApp.ViewState.stateToViewState(state:))
15+
destination: CounterApp.RootView(
16+
system: CounterApp
17+
.System
18+
.counter
19+
.uiSystem()
1820
.run()
1921
))
2022

2123
NavigationLink("Giphy Trends Application",
2224
destination: GifList.RootView(
23-
system: GifList.System.make()
25+
system: GifList
26+
.System
27+
.gifOverview
2428
.uiSystem(viewStateFactory: GifList.ViewState.stateToViewState(state:))
2529
.run()
2630
))

Examples/Examples/CounterApp/System/Events.swift renamed to Examples/Examples/CounterApp/System/CounterApp+Events.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Events.swift
2+
// CounterApp+Events.swift
33
// Examples
44
//
55
// Created by Thibault Wittemberg on 2021-01-12.

Examples/Examples/CounterApp/System/SideEffects.swift renamed to Examples/Examples/CounterApp/System/CounterApp+SideEffects.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// SideEffects.swift
2+
// CounterApp+SideEffects.swift
33
// Examples
44
//
55
// Created by Thibault Wittemberg on 2021-01-12.

Examples/Examples/CounterApp/System/States.swift renamed to Examples/Examples/CounterApp/System/CounterApp+States.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// States.swift
2+
// CounterApp+States.swift
33
// Examples
44
//
55
// Created by Thibault Wittemberg on 2021-01-12.

Examples/Examples/CounterApp/System/System.swift renamed to Examples/Examples/CounterApp/System/CounterApp+System.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// System.swift
2+
// CounterApp+System.swift
33
// Examples
44
//
55
// Created by Thibault Wittemberg on 2021-01-12.
@@ -30,8 +30,8 @@ extension CounterApp.System {
3030
}
3131

3232
Transitions {
33-
CounterApp.Transitions.fixedTransitions
34-
CounterApp.Transitions.resetTransitions
33+
CounterApp.Transitions.fixedTransition
34+
CounterApp.Transitions.resetTransition
3535
CounterApp.Transitions.decreasingTransitions
3636
CounterApp.Transitions.increasingTransitions
3737
}

Examples/Examples/CounterApp/System/Transitions.swift renamed to Examples/Examples/CounterApp/System/CounterApp+Transitions.swift

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Transitions.swift
2+
// CounterApp+Transitions.swift
33
// Examples
44
//
55
// Created by Thibault Wittemberg on 2021-01-12.
@@ -13,16 +13,13 @@ extension CounterApp {
1313
}
1414

1515
extension CounterApp.Transitions {
16-
static let fixedTransitions = Transitions {
17-
Transition(from: CounterApp.States.Fixed.self, on: CounterApp.Events.TogglePause.self) { state, _ -> State in
18-
CounterApp.States.Decreasing(value: state.value, isPaused: false)
19-
}
16+
static let fixedTransition = Transition(from: CounterApp.States.Fixed.self,
17+
on: CounterApp.Events.TogglePause.self) { state, _ -> State in
18+
CounterApp.States.Decreasing(value: state.value, isPaused: false)
2019
}
2120

22-
static let resetTransitions = Transitions {
23-
Transition(from: AnyState.self, on: CounterApp.Events.Reset.self) { _, event -> State in
24-
CounterApp.States.Fixed(value: event.value)
25-
}
21+
static let resetTransition = Transition(from: AnyState.self, on: CounterApp.Events.Reset.self) { _, event -> State in
22+
CounterApp.States.Fixed(value: event.value)
2623
}
2724

2825
static let decreasingTransitions = Transitions {
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
//
2+
// CounterApp+RootView.swift
3+
// Examples
4+
//
5+
// Created by Thibault Wittemberg on 2021-01-12.
6+
//
7+
8+
import Feedbacks
9+
import SwiftUI
10+
11+
extension CounterApp {
12+
struct RootView: View {
13+
@ObservedObject
14+
var system: UISystem<RawState>
15+
16+
var body: some View {
17+
VStack {
18+
HStack {
19+
Text("state = \(self.counterDescription(from: self.system.state))")
20+
.font(.footnote)
21+
.padding()
22+
Spacer()
23+
}
24+
Spacer()
25+
Text("\(self.counterValue(from: self.system.state))")
26+
.font(.system(size: 59))
27+
.foregroundColor(self.counterColor(from: self.system.state))
28+
Spacer()
29+
HStack {
30+
Spacer()
31+
Button(action: {
32+
self.system.emit(CounterApp.Events.Reset(value: 10))
33+
}) {
34+
Text("Reset")
35+
.font(.system(size: 25))
36+
}
37+
.frame(width: 100, height: 30, alignment: .center)
38+
.padding(10)
39+
.background(Color.gray)
40+
.opacity(self.isCounterFixed(from: self.system.state) ? 0.5 : 1.0)
41+
.foregroundColor(.white)
42+
.cornerRadius(20)
43+
.disabled(self.isCounterFixed(from: self.system.state))
44+
.animation(.default)
45+
46+
Spacer()
47+
48+
Button(action: {
49+
self.system.emit(CounterApp.Events.TogglePause())
50+
}) {
51+
Text("\(self.isCounterPaused(from: self.system.state) ? "Start": "Stop")")
52+
.font(.system(size: 25))
53+
}
54+
.frame(width: 100, height: 30, alignment: .center)
55+
.padding(10)
56+
.background(Color.gray)
57+
.foregroundColor(.white)
58+
.cornerRadius(20)
59+
60+
Spacer()
61+
}
62+
.padding(20)
63+
}
64+
.padding(20)
65+
}
66+
67+
private func counterValue(from rawState: RawState) -> Int {
68+
switch rawState.state {
69+
case let fixed as CounterApp.States.Fixed: return fixed.value
70+
case let decreasing as CounterApp.States.Decreasing: return decreasing.value
71+
case let increasing as CounterApp.States.Increasing: return increasing.value
72+
default: return 0
73+
}
74+
}
75+
76+
private func counterColor(from rawState: RawState) -> Color {
77+
switch rawState.state {
78+
case is CounterApp.States.Fixed: return .green
79+
case is CounterApp.States.Decreasing: return .red
80+
case is CounterApp.States.Increasing: return .blue
81+
default: return .accentColor
82+
}
83+
}
84+
85+
private func isCounterFixed(from rawState: RawState) -> Bool {
86+
guard rawState.state is CounterApp.States.Fixed else { return false }
87+
return true
88+
}
89+
90+
private func isCounterPaused(from rawState: RawState) -> Bool {
91+
switch rawState.state {
92+
case is CounterApp.States.Fixed: return true
93+
case let decreasing as CounterApp.States.Decreasing: return decreasing.isPaused
94+
case let increasing as CounterApp.States.Increasing: return increasing.isPaused
95+
default: return true
96+
}
97+
}
98+
99+
private func counterDescription(from rawState: RawState) -> String {
100+
switch rawState.state {
101+
case let fixed as CounterApp.States.Fixed:
102+
return "Fixed(value: \(fixed.value))"
103+
case let decreasing as CounterApp.States.Decreasing:
104+
return "Decreasing(value: \(decreasing.value), paused: \(decreasing.isPaused))"
105+
case let increasing as CounterApp.States.Increasing:
106+
return "Increasing(value: \(increasing.value), paused: \(increasing.isPaused))"
107+
default: return "undefined"
108+
}
109+
}
110+
}
111+
}
112+
113+
struct CounterApp_RootView_Previews: PreviewProvider {
114+
static var previews: some View {
115+
CounterApp.RootView(system: CounterApp.System.counter.uiSystem())
116+
}
117+
}

0 commit comments

Comments
 (0)