Skip to content

Commit eeb53aa

Browse files
committed
Move generate_id.dart to api
1 parent 583f379 commit eeb53aa

21 files changed

+211
-144
lines changed

lib/codelessly_api.dart

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44

55
library codelessly_api;
66

7+
export 'src/api/constants.dart';
8+
export 'src/api/custom_component.dart';
9+
export 'src/api/generate_id.dart';
10+
export 'src/api/math_helper.dart';
711
export 'src/api/mixins.dart';
812
export 'src/api/models/models.dart';
913
export 'src/api/node_json_converter.dart';
1014
export 'src/api/nodes/nodes.dart';
1115
export 'src/api/utils.dart';
12-
export 'src/api/constants.dart';
13-
export 'src/api/custom_component.dart';
14-
export 'src/api/math_helper.dart';

lib/src/api/generate_id.dart

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import 'dart:math' as math;
2+
3+
/// Modeled after base64 web-safe chars, but ordered by ASCII.
4+
const String _kPushChars =
5+
'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz';
6+
7+
/// Implementation from https://gist.github.com/mikelehen/3596a30bd69384624c11
8+
///
9+
/// Fancy ID generator that creates 20-character string identifiers with the following properties:
10+
///
11+
/// 1. They're based on timestamp so that they sort *after* any existing ids.
12+
/// 2. They contain 72-bits of random data after the timestamp so that IDs won't collide with other clients' IDs.
13+
/// 3. They sort *lexicographically* (so the timestamp is converted to characters that will sort properly).
14+
/// 4. They're monotonically increasing. Even if you generate more than one in the same timestamp, the
15+
/// latter ones will sort after the former ones. We do this by using the previous random bits
16+
/// but "incrementing" them by 1 (only in the case of a timestamp collision).
17+
String generateId() {
18+
int lastPushTime = 0;
19+
final List<int> randomSuffix = List.filled(12, 0);
20+
final math.Random random = math.Random.secure();
21+
22+
final int now = DateTime.now().toUtc().millisecondsSinceEpoch;
23+
String id = _toPushIdBase64(now, 8);
24+
25+
if (now != lastPushTime) {
26+
for (int i = 0; i < 12; i += 1) {
27+
randomSuffix[i] = random.nextInt(63);
28+
}
29+
} else {
30+
int i;
31+
for (i = 11; i >= 0 && randomSuffix[i] == 62; i--) {
32+
randomSuffix[i] = 0;
33+
}
34+
randomSuffix[i] += 1;
35+
}
36+
final String suffixStr = randomSuffix.map((int i) => _kPushChars[i]).join();
37+
lastPushTime = now;
38+
39+
return '$id$suffixStr';
40+
}
41+
42+
String _toPushIdBase64(int value, int numChars) {
43+
List<String> chars = List.filled(numChars, '');
44+
for (int i = numChars - 1; i >= 0; i -= 1) {
45+
chars[i] = _kPushChars[value % 63];
46+
value = (value / 63).floor();
47+
}
48+
assert(value == 0);
49+
return chars.join();
50+
}

lib/src/api/models/effect.dart

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import 'package:equatable/equatable.dart';
66
import 'package:json_annotation/json_annotation.dart';
77

8+
import '../generate_id.dart';
89
import '../mixins.dart';
910
import 'models.dart';
1011

@@ -43,6 +44,9 @@ enum ShadowProperty {
4344
/// A visual effect such as a shadow or blur.
4445
@JsonSerializable()
4546
class Effect with EquatableMixin, SerializableMixin {
47+
/// Unique identifier of the effect.
48+
final String id;
49+
4650
/// Type of effect.
4751
final EffectType type;
4852

@@ -66,59 +70,64 @@ class Effect with EquatableMixin, SerializableMixin {
6670
final Vec? offset;
6771

6872
/// Creates new [Effect] with given data.
69-
const Effect({
73+
Effect({
74+
String? id,
7075
required this.type,
7176
required this.radius,
7277
this.visible = true,
7378
this.color,
7479
this.blendMode,
7580
this.offset,
7681
this.spread,
77-
});
82+
}) : id = id ?? generateId();
7883

7984
/// Creates a new [Effect] with drop shadow.
80-
const Effect.dropShadow({
85+
Effect.dropShadow({
86+
String? id,
8187
this.type = EffectType.dropShadow,
8288
required this.radius,
8389
this.visible = true,
8490
required this.color,
8591
required this.offset,
8692
required this.spread,
8793
this.blendMode,
88-
});
94+
}) : id = id ?? generateId();
8995

9096
/// Creates a new [Effect] with inner shadow.
91-
const Effect.innerShadow({
97+
Effect.innerShadow({
98+
String? id,
9299
this.type = EffectType.innerShadow,
93100
required this.radius,
94101
this.visible = true,
95102
required this.color,
96103
required this.offset,
97104
required this.spread,
98105
this.blendMode,
99-
});
106+
}) : id = id ?? generateId();
100107

101108
/// Creates a new [Effect] with layer blur.
102-
const Effect.layerBlur({
109+
Effect.layerBlur({
110+
String? id,
103111
this.type = EffectType.layerBlur,
104112
required this.radius,
105113
this.visible = true,
106114
this.color,
107115
this.blendMode,
108116
this.offset,
109117
this.spread,
110-
});
118+
}) : id = id ?? generateId();
111119

112120
/// Creates a new [Effect] with background blur.
113-
const Effect.backgroundBlur({
121+
Effect.backgroundBlur({
122+
String? id,
114123
this.type = EffectType.backgroundBlur,
115124
required this.radius,
116125
this.visible = true,
117126
this.color,
118127
this.blendMode,
119128
this.offset,
120129
this.spread,
121-
});
130+
}) : id = id ?? generateId();
122131

123132
/// Duplicates this instance with given data overrides.
124133
Effect copyWith({

lib/src/api/models/input_decoration.dart

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -174,52 +174,33 @@ class InputDecorationModel with EquatableMixin, SerializableMixin {
174174
final BoxConstraintsModel constraints;
175175

176176
/// Creates [InputDecorationModel] with given data.
177-
const InputDecorationModel({
177+
InputDecorationModel({
178178
this.icon = const MultiSourceIconModel(),
179179
this.labelText,
180-
this.labelStyle = const TextProp.general(
181-
fontSize: 14,
182-
fills: [PaintModel.blackPaint],
183-
),
184-
this.floatingLabelStyle = const TextProp.general(
185-
fontSize: 14,
186-
fills: [PaintModel.blackPaint],
187-
),
180+
TextProp? labelStyle,
181+
TextProp? floatingLabelStyle,
188182
this.helperText,
189-
this.helperStyle = const TextProp.general(
190-
fontSize: 14,
191-
fills: [PaintModel.blackPaint],
192-
),
183+
TextProp? helperStyle,
193184
this.helperMaxLines = 1,
194185
this.hintText,
195-
this.hintStyle = const TextProp.general(
196-
fontSize: 14,
197-
fills: [
198-
PaintModel.solid(visible: true, opacity: 1, color: ColorRGB.grey)
199-
],
200-
),
186+
TextProp? hintStyle,
201187
this.hintMaxLines = 1,
202188
this.errorText,
203-
this.errorStyle = const TextProp.general(
204-
fills: [PaintModel.solid(visible: true, opacity: 1, color: ColorRGB.red)],
205-
),
189+
TextProp? errorStyle,
206190
this.errorMaxLines = 1,
207191
this.floatingLabelBehavior = FloatingLabelBehaviorEnum.auto,
208192
this.isCollapsed = false,
209193
this.isDense = true,
210194
this.prefixIcon = const MultiSourceIconModel(),
211195
this.prefixIconConstraints = const BoxConstraintsModel(),
212196
this.prefixText,
213-
this.prefixStyle = const TextProp.general(),
197+
TextProp? prefixStyle,
214198
this.suffixIcon = const MultiSourceIconModel(),
215199
this.suffixText,
216-
this.suffixStyle = const TextProp.general(
217-
fontSize: 14,
218-
fills: [PaintModel.blackPaint],
219-
),
200+
TextProp? suffixStyle,
220201
this.suffixIconConstraints = const BoxConstraintsModel(),
221202
this.counterText,
222-
this.counterStyle = const TextProp.general(),
203+
TextProp? counterStyle,
223204
this.filled = false,
224205
this.fillColor = ColorRGBA.grey10,
225206
this.focusColor = ColorRGBA.black,
@@ -244,7 +225,20 @@ class InputDecorationModel with EquatableMixin, SerializableMixin {
244225
this.semanticCounterText,
245226
this.alignLabelWithHint = true,
246227
this.constraints = const BoxConstraintsModel(),
247-
});
228+
}) : labelStyle = labelStyle ?? TextProp(fontSize: 14),
229+
floatingLabelStyle = floatingLabelStyle ??
230+
TextProp.general(fontSize: 14, fills: [PaintModel.blackPaint]),
231+
helperStyle = helperStyle ??
232+
TextProp.general(fontSize: 14, fills: [PaintModel.blackPaint]),
233+
hintStyle = hintStyle ??
234+
TextProp.general(
235+
fontSize: 14, fills: [PaintModel.solid(color: ColorRGB.grey)]),
236+
errorStyle = errorStyle ??
237+
TextProp.general(fills: [PaintModel.solid(color: ColorRGB.red)]),
238+
prefixStyle = prefixStyle ?? TextProp.general(),
239+
suffixStyle = suffixStyle ??
240+
TextProp.general(fontSize: 14, fills: [PaintModel.blackPaint]),
241+
counterStyle = counterStyle ?? TextProp.general();
248242

249243
/// Duplicates this instance with given data overrides.
250244
InputDecorationModel copyWith({

lib/src/api/models/input_decoration.g.dart

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

0 commit comments

Comments
 (0)