+1
lib/models/gallery.dart
+1
lib/models/gallery.dart
+33
-3
lib/models/gallery.freezed.dart
+33
-3
lib/models/gallery.freezed.dart
···
32
32
int? get commentCount => throw _privateConstructorUsedError;
33
33
GalleryViewer? get viewer => throw _privateConstructorUsedError;
34
34
List<Map<String, dynamic>>? get facets => throw _privateConstructorUsedError;
35
+
List<String>? get cameras => throw _privateConstructorUsedError;
35
36
36
37
/// Serializes this Gallery to a JSON map.
37
38
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
···
59
60
int? commentCount,
60
61
GalleryViewer? viewer,
61
62
List<Map<String, dynamic>>? facets,
63
+
List<String>? cameras,
62
64
});
63
65
64
66
$ProfileCopyWith<$Res>? get creator;
···
91
93
Object? commentCount = freezed,
92
94
Object? viewer = freezed,
93
95
Object? facets = freezed,
96
+
Object? cameras = freezed,
94
97
}) {
95
98
return _then(
96
99
_value.copyWith(
···
138
141
? _value.facets
139
142
: facets // ignore: cast_nullable_to_non_nullable
140
143
as List<Map<String, dynamic>>?,
144
+
cameras: freezed == cameras
145
+
? _value.cameras
146
+
: cameras // ignore: cast_nullable_to_non_nullable
147
+
as List<String>?,
141
148
)
142
149
as $Val,
143
150
);
···
192
199
int? commentCount,
193
200
GalleryViewer? viewer,
194
201
List<Map<String, dynamic>>? facets,
202
+
List<String>? cameras,
195
203
});
196
204
197
205
@override
···
225
233
Object? commentCount = freezed,
226
234
Object? viewer = freezed,
227
235
Object? facets = freezed,
236
+
Object? cameras = freezed,
228
237
}) {
229
238
return _then(
230
239
_$GalleryImpl(
···
272
281
? _value._facets
273
282
: facets // ignore: cast_nullable_to_non_nullable
274
283
as List<Map<String, dynamic>>?,
284
+
cameras: freezed == cameras
285
+
? _value._cameras
286
+
: cameras // ignore: cast_nullable_to_non_nullable
287
+
as List<String>?,
275
288
),
276
289
);
277
290
}
···
292
305
this.commentCount,
293
306
this.viewer,
294
307
final List<Map<String, dynamic>>? facets,
308
+
final List<String>? cameras,
295
309
}) : _items = items,
296
-
_facets = facets;
310
+
_facets = facets,
311
+
_cameras = cameras;
297
312
298
313
factory _$GalleryImpl.fromJson(Map<String, dynamic> json) =>
299
314
_$$GalleryImplFromJson(json);
···
334
349
return EqualUnmodifiableListView(value);
335
350
}
336
351
352
+
final List<String>? _cameras;
353
+
@override
354
+
List<String>? get cameras {
355
+
final value = _cameras;
356
+
if (value == null) return null;
357
+
if (_cameras is EqualUnmodifiableListView) return _cameras;
358
+
// ignore: implicit_dynamic_type
359
+
return EqualUnmodifiableListView(value);
360
+
}
361
+
337
362
@override
338
363
String toString() {
339
-
return 'Gallery(uri: $uri, cid: $cid, title: $title, description: $description, items: $items, creator: $creator, createdAt: $createdAt, favCount: $favCount, commentCount: $commentCount, viewer: $viewer, facets: $facets)';
364
+
return 'Gallery(uri: $uri, cid: $cid, title: $title, description: $description, items: $items, creator: $creator, createdAt: $createdAt, favCount: $favCount, commentCount: $commentCount, viewer: $viewer, facets: $facets, cameras: $cameras)';
340
365
}
341
366
342
367
@override
···
358
383
(identical(other.commentCount, commentCount) ||
359
384
other.commentCount == commentCount) &&
360
385
(identical(other.viewer, viewer) || other.viewer == viewer) &&
361
-
const DeepCollectionEquality().equals(other._facets, _facets));
386
+
const DeepCollectionEquality().equals(other._facets, _facets) &&
387
+
const DeepCollectionEquality().equals(other._cameras, _cameras));
362
388
}
363
389
364
390
@JsonKey(includeFromJson: false, includeToJson: false)
···
376
402
commentCount,
377
403
viewer,
378
404
const DeepCollectionEquality().hash(_facets),
405
+
const DeepCollectionEquality().hash(_cameras),
379
406
);
380
407
381
408
/// Create a copy of Gallery
···
405
432
final int? commentCount,
406
433
final GalleryViewer? viewer,
407
434
final List<Map<String, dynamic>>? facets,
435
+
final List<String>? cameras,
408
436
}) = _$GalleryImpl;
409
437
410
438
factory _Gallery.fromJson(Map<String, dynamic> json) = _$GalleryImpl.fromJson;
···
431
459
GalleryViewer? get viewer;
432
460
@override
433
461
List<Map<String, dynamic>>? get facets;
462
+
@override
463
+
List<String>? get cameras;
434
464
435
465
/// Create a copy of Gallery
436
466
/// with the given fields replaced by the non-null parameter values.
+4
lib/models/gallery.g.dart
+4
lib/models/gallery.g.dart
···
27
27
facets: (json['facets'] as List<dynamic>?)
28
28
?.map((e) => e as Map<String, dynamic>)
29
29
.toList(),
30
+
cameras: (json['cameras'] as List<dynamic>?)
31
+
?.map((e) => e as String)
32
+
.toList(),
30
33
);
31
34
32
35
Map<String, dynamic> _$$GalleryImplToJson(_$GalleryImpl instance) =>
···
42
45
'commentCount': instance.commentCount,
43
46
'viewer': instance.viewer,
44
47
'facets': instance.facets,
48
+
'cameras': instance.cameras,
45
49
};
+6
lib/screens/gallery_page.dart
+6
lib/screens/gallery_page.dart
···
7
7
import 'package:grain/screens/hashtag_page.dart';
8
8
import 'package:grain/screens/profile_page.dart';
9
9
import 'package:grain/widgets/app_image.dart';
10
+
import 'package:grain/widgets/camera_pills.dart';
10
11
import 'package:grain/widgets/faceted_text.dart';
11
12
import 'package:grain/widgets/gallery_action_buttons.dart';
12
13
import 'package:grain/widgets/gallery_photo_view.dart';
···
249
250
MaterialPageRoute(builder: (_) => HashtagPage(hashtag: tag)),
250
251
),
251
252
),
253
+
),
254
+
if ((gallery.cameras?.isNotEmpty ?? false))
255
+
Padding(
256
+
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
257
+
child: CameraPills(cameras: gallery.cameras!),
252
258
),
253
259
if (isLoggedIn)
254
260
Padding(
+2
-26
lib/screens/profile_page.dart
+2
-26
lib/screens/profile_page.dart
···
10
10
import 'package:grain/widgets/app_image.dart';
11
11
import 'package:grain/widgets/edit_profile_sheet.dart';
12
12
import 'package:grain/widgets/faceted_text.dart';
13
+
import 'package:grain/widgets/camera_pills.dart';
13
14
import 'package:url_launcher/url_launcher.dart';
14
15
15
16
import 'gallery_page.dart';
···
284
285
),
285
286
if ((profile.cameras?.isNotEmpty ?? false)) ...[
286
287
const SizedBox(height: 16),
287
-
Wrap(
288
-
spacing: 8,
289
-
runSpacing: 4,
290
-
children: profile.cameras!
291
-
.map(
292
-
(camera) => Container(
293
-
padding: const EdgeInsets.symmetric(
294
-
horizontal: 12,
295
-
vertical: 4,
296
-
),
297
-
decoration: BoxDecoration(
298
-
color: theme.colorScheme.surface,
299
-
borderRadius: BorderRadius.circular(999),
300
-
),
301
-
child: Text(
302
-
'📷 $camera',
303
-
style: TextStyle(
304
-
color: theme.colorScheme.onSurface,
305
-
fontWeight: FontWeight.w500,
306
-
fontSize: 12,
307
-
),
308
-
),
309
-
),
310
-
)
311
-
.toList(),
312
-
),
288
+
CameraPills(cameras: profile.cameras!),
313
289
],
314
290
if ((profile.description ?? '').isNotEmpty) ...[
315
291
const SizedBox(height: 16),
+39
lib/widgets/camera_pills.dart
+39
lib/widgets/camera_pills.dart
···
1
+
import 'package:flutter/material.dart';
2
+
3
+
class CameraPills extends StatelessWidget {
4
+
final List<String> cameras;
5
+
final EdgeInsetsGeometry? padding;
6
+
const CameraPills({super.key, required this.cameras, this.padding});
7
+
8
+
@override
9
+
Widget build(BuildContext context) {
10
+
final theme = Theme.of(context);
11
+
if (cameras.isEmpty) return SizedBox.shrink();
12
+
return Padding(
13
+
padding: padding ?? EdgeInsets.zero,
14
+
child: Wrap(
15
+
spacing: 8,
16
+
runSpacing: 4,
17
+
children: cameras
18
+
.map(
19
+
(camera) => Container(
20
+
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
21
+
decoration: BoxDecoration(
22
+
color: theme.colorScheme.surface,
23
+
borderRadius: BorderRadius.circular(999),
24
+
),
25
+
child: Text(
26
+
'📷 $camera',
27
+
style: TextStyle(
28
+
color: theme.colorScheme.onSurface,
29
+
fontWeight: FontWeight.w500,
30
+
fontSize: 12,
31
+
),
32
+
),
33
+
),
34
+
)
35
+
.toList(),
36
+
),
37
+
);
38
+
}
39
+
}