• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Duit-Foundation / flutter_duit / 22107347802

17 Feb 2026 04:47PM UTC coverage: 80.64% (-0.02%) from 80.663%
22107347802

push

github

web-flow
patch: Fixed GridView issue with property parsing (#337)

5 of 7 new or added lines in 3 files covered. (71.43%)

4890 of 6064 relevant lines covered (80.64%)

36.12 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

42.11
/lib/src/controller/view_controller.dart
1
import "dart:async";
2

3
import "package:duit_kernel/duit_kernel.dart";
4
import "package:flutter/foundation.dart";
5
import "package:flutter_duit/src/utils/invoker.dart";
6
import "package:flutter_duit/src/controller/index.dart";
7

8
/// The controller for a UI element.
9
///
10
/// This class is responsible for managing the state and behavior of a UI element.
11
/// It implements the [UIElementController] interface and uses the [ChangeNotifier]
12
/// mixin to provide change notification to listeners.
13
final class ViewController<T>
14
    with ChangeNotifier, ActionInvoker
15
    implements UIElementController {
16
  /// The attributes associated with the UI element.
17
  ///
18
  /// This property holds the attributes of the UI element that the `ViewController` controls.
19
  /// It can be used to access and modify the attributes of the UI element.
20
  @override
21
  ViewAttribute attributes;
22

23
  /// The server action associated with the UI element.
24
  ///
25
  /// This property holds the server action that is triggered when the UI element is interacted with.
26
  @override
27
  ServerAction? action;
28

29
  /// The driver that controls the UI element.
30
  ///
31
  /// This property holds the driver object that is responsible for interacting with the UI element.
32
  @override
33
  UIDriver driver;
34

35
  /// The unique identifier of the UI element.
36
  ///
37
  /// This property holds the unique identifier that is assigned to the UI element.
38
  @override
39
  String id;
40

41
  /// The type of the UI element.
42
  ///
43
  /// This property holds the type of the UI element that the `ViewController` controls.
44
  @override
45
  String type;
46

47
  /// The tag associated with the UI element.
48
  ///
49
  /// This property holds an optional tag that can be used to further categorize the UI element.
50
  @override
51
  String? tag;
52

53
  /// Creates a new instance of the `ViewController` class.
54
  ///
55
  /// The [id] parameter specifies the unique identifier of the UI element.
56
  /// The [driver] parameter specifies the driver that controls the UI element.
57
  /// The [type] parameter specifies the type of the UI element.
58
  /// The [action] parameter specifies the server action associated with the UI element.
59
  /// The [attributes] parameter specifies the initial attributes of the UI element.
60
  /// The [tag] parameter specifies the tag associated with the UI element.
61
  ViewController({
408✔
62
    required this.id,
63
    required this.driver,
64
    required this.type,
65
    required this.attributes,
66
    this.action,
67
    this.tag,
68
  });
69

70
  /// Updates the state of the UI element with new attributes.
71
  ///
72
  /// The [newAttrs] parameter specifies the new attributes to be applied to the UI element.
73
  @override
308✔
74
  void updateState(Map<String, dynamic> newState) {
75
    attributes.payload.addAll(newState);
924✔
76
    notifyListeners();
308✔
77
  }
78

79
  void _perform(ServerAction action) {
48✔
80
    final opts = action.executionOptions;
48✔
81
    if (opts != null) {
82
      switch (opts.modifier) {
×
83
        case ExecutionModifier.throttle:
×
84
          throttleWithArgs(
×
85
            action.eventName,
×
86
            driver.execute,
×
87
            action,
88
            duration: opts.duration,
×
89
          );
90
          break;
91
        case ExecutionModifier.debounce:
×
92
          debounceWithArgs(
×
93
            action.eventName,
×
94
            driver.execute,
×
95
            action,
96
            duration: opts.duration,
×
97
          );
98
          break;
99
      }
100
    } else {
101
      driver.execute(action);
96✔
102
    }
103
  }
104

105
  FutureOr<void> _performAsync(ServerAction action) async {
×
106
    final opts = action.executionOptions;
×
107
    if (opts != null) {
108
      switch (opts.modifier) {
×
109
        case ExecutionModifier.throttle:
×
110
          throttleWithArgs(
×
111
            action.eventName,
×
112
            driver.execute,
×
113
            action,
114
            duration: opts.duration,
×
115
          );
116
          break;
117
        case ExecutionModifier.debounce:
×
118
          debounceWithArgs(
×
119
            action.eventName,
×
120
            driver.execute,
×
121
            action,
122
            duration: opts.duration,
×
123
          );
124
          break;
125
      }
126
    } else {
127
      await driver.execute(action);
×
128
    }
129
  }
130

131
  /// Performs the related action of the UI element.
132
  ///
133
  /// This method is called when the UI element is interacted with and the associated
134
  /// server action is not null. It executes the server action using the driver.
135
  @override
48✔
136
  void performRelatedAction() {
137
    if (action != null) {
48✔
138
      _perform(action!);
48✔
139
    } else {
140
      driver.logWarning("An attempt was made to call an action, but the action is missing.", null, StackTrace.current,);
72✔
141
    }
142
  }
143

144
  @override
×
145
  Future<void> performRelatedActionAsync() async {
146
    if (action != null) {
×
147
      await _performAsync(action!);
×
148
    } else {
NEW
149
      driver.logWarning("An attempt was made to call an action, but the action is missing.", null, StackTrace.current,);
×
150
    }
151
  }
152

153
  @override
48✔
154
  void performAction(ServerAction? action) {
155
    if (action != null) {
156
      _perform(action);
44✔
157
    } else {
158
      driver.logWarning("An attempt was made to call an action, but the action is missing.", null, StackTrace.current,);
24✔
159
    }
160
  }
161

162
  @override
×
163
  Future<void> performActionAsync(ServerAction? action) async {
164
    if (action != null) {
165
      await _performAsync(action);
×
166
    } else {
NEW
167
      driver.logWarning("An attempt was made to call an action, but the action is missing.", null, StackTrace.current,);
×
168
    }
169
  }
170

171
  @override
400✔
172
  void detach() {
173
    driver.detachController(id);
1,200✔
174
    cancelAll();
400✔
175
  }
176

177
  @override
178
  late final StreamController<RemoteCommand> commandChannel;
179

180
  @override
16✔
181
  FutureOr<void> emitCommand(RemoteCommand command) async {
182
    try {
183
      final specifiedCommand = SpecCommand(command).specify();
32✔
184
      commandChannel.add(specifiedCommand);
32✔
185
    } catch (e, s) {
186
      driver.logError(
×
187
        "Error while emitting command",
188
        e,
189
        s,
190
      );
191
    }
192
  }
193

194
  @override
12✔
195
  void removeCommandListener() => commandChannel.close();
24✔
196

197
  @override
400✔
198
  void listenCommand(CommandListener callback) {
199
    commandChannel = StreamController<RemoteCommand>()..stream.listen(callback);
1,600✔
200
  }
201
}
202

203
typedef CommandListener = Future<void> Function(RemoteCommand command);
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc