+153
-148
lib/screens/create_gallery_page.dart
+153
-148
lib/screens/create_gallery_page.dart
···
299
299
),
300
300
child: SafeArea(
301
301
bottom: true,
302
-
child: SingleChildScrollView(
303
-
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16),
304
-
child: Column(
305
-
crossAxisAlignment: CrossAxisAlignment.start,
306
-
mainAxisSize: MainAxisSize.min,
307
-
children: [
308
-
PlainTextField(
309
-
label: 'Title',
310
-
controller: _titleController,
311
-
hintText: 'Enter a title',
312
-
),
313
-
Padding(
314
-
padding: const EdgeInsets.only(top: 4),
315
-
child: Row(
316
-
mainAxisAlignment: MainAxisAlignment.spaceBetween,
317
-
children: [
318
-
const SizedBox(),
319
-
Text(
320
-
'${_titleController.text.characters.length}/100',
321
-
style: theme.textTheme.bodySmall?.copyWith(
322
-
color: _titleController.text.characters.length > 100
323
-
? theme.colorScheme.error
324
-
: theme.textTheme.bodySmall?.color,
325
-
),
326
-
),
327
-
],
302
+
child: GestureDetector(
303
+
behavior: HitTestBehavior.translucent,
304
+
onTap: () => FocusScope.of(context).unfocus(),
305
+
child: SingleChildScrollView(
306
+
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16),
307
+
child: Column(
308
+
crossAxisAlignment: CrossAxisAlignment.start,
309
+
mainAxisSize: MainAxisSize.min,
310
+
children: [
311
+
PlainTextField(
312
+
label: 'Title',
313
+
controller: _titleController,
314
+
hintText: 'Enter a title',
328
315
),
329
-
),
330
-
const SizedBox(height: 16),
331
-
PlainTextField(
332
-
label: 'Description',
333
-
controller: _descController,
334
-
maxLines: 6,
335
-
hintText: 'Enter a description',
336
-
),
337
-
Padding(
338
-
padding: const EdgeInsets.only(top: 4),
339
-
child: Row(
340
-
mainAxisAlignment: MainAxisAlignment.spaceBetween,
341
-
children: [
342
-
const SizedBox(),
343
-
Text(
344
-
'${_descController.text.characters.length}/1000',
345
-
style: theme.textTheme.bodySmall?.copyWith(
346
-
color: _descController.text.characters.length > 1000
347
-
? theme.colorScheme.error
348
-
: theme.textTheme.bodySmall?.color,
316
+
Padding(
317
+
padding: const EdgeInsets.only(top: 4),
318
+
child: Row(
319
+
mainAxisAlignment: MainAxisAlignment.spaceBetween,
320
+
children: [
321
+
const SizedBox(),
322
+
Text(
323
+
'${_titleController.text.characters.length}/100',
324
+
style: theme.textTheme.bodySmall?.copyWith(
325
+
color: _titleController.text.characters.length > 100
326
+
? theme.colorScheme.error
327
+
: theme.textTheme.bodySmall?.color,
328
+
),
349
329
),
350
-
),
351
-
],
330
+
],
331
+
),
352
332
),
353
-
),
354
-
const SizedBox(height: 16),
355
-
if (widget.gallery == null)
356
-
Row(
357
-
children: [
358
-
Expanded(
359
-
child: Text(
360
-
'Include image metadata (EXIF)',
361
-
style: theme.textTheme.bodyMedium,
362
-
),
363
-
),
364
-
Switch(
365
-
value: _includeExif,
366
-
onChanged: (val) {
367
-
setState(() {
368
-
_includeExif = val;
369
-
});
370
-
},
371
-
),
372
-
],
333
+
const SizedBox(height: 16),
334
+
PlainTextField(
335
+
label: 'Description',
336
+
controller: _descController,
337
+
maxLines: 6,
338
+
hintText: 'Enter a description',
373
339
),
374
-
const SizedBox(height: 16),
375
-
if (widget.gallery == null) ...[
376
340
Padding(
377
-
padding: const EdgeInsets.only(bottom: 8.0),
378
-
child: Text(
379
-
"You can add up to 10 photos when initially creating a gallery, but you can add more later on. Galleries can capture a moment in time or evolve as an ongoing collection.",
380
-
style: theme.textTheme.bodySmall?.copyWith(color: theme.hintColor),
341
+
padding: const EdgeInsets.only(top: 4),
342
+
child: Row(
343
+
mainAxisAlignment: MainAxisAlignment.spaceBetween,
344
+
children: [
345
+
const SizedBox(),
346
+
Text(
347
+
'${_descController.text.characters.length}/1000',
348
+
style: theme.textTheme.bodySmall?.copyWith(
349
+
color: _descController.text.characters.length > 1000
350
+
? theme.colorScheme.error
351
+
: theme.textTheme.bodySmall?.color,
352
+
),
353
+
),
354
+
],
381
355
),
382
356
),
383
-
Row(
384
-
children: [
385
-
Expanded(
386
-
child: AppButton(
387
-
label: 'Add photos (${_images.length}/10)',
388
-
onPressed: _pickImages,
389
-
icon: AppIcons.photoLibrary,
390
-
variant: AppButtonVariant.primary,
391
-
height: 40,
392
-
fontSize: 15,
393
-
borderRadius: 6,
357
+
const SizedBox(height: 16),
358
+
if (widget.gallery == null)
359
+
Row(
360
+
children: [
361
+
Expanded(
362
+
child: Text(
363
+
'Include image metadata (EXIF)',
364
+
style: theme.textTheme.bodyMedium,
365
+
),
366
+
),
367
+
Switch(
368
+
value: _includeExif,
369
+
onChanged: (val) {
370
+
setState(() {
371
+
_includeExif = val;
372
+
});
373
+
},
394
374
),
395
-
),
396
-
],
397
-
),
398
-
],
399
-
if (_images.isNotEmpty) ...[
375
+
],
376
+
),
400
377
const SizedBox(height: 16),
401
-
GridView.builder(
402
-
shrinkWrap: true,
403
-
physics: const NeverScrollableScrollPhysics(),
404
-
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
405
-
crossAxisCount: 3,
406
-
crossAxisSpacing: 8,
407
-
mainAxisSpacing: 8,
378
+
if (widget.gallery == null) ...[
379
+
Padding(
380
+
padding: const EdgeInsets.only(bottom: 8.0),
381
+
child: Text(
382
+
"You can add up to 10 photos when initially creating a gallery, but you can add more later on. Galleries can capture a moment in time or evolve as an ongoing collection.",
383
+
style: theme.textTheme.bodySmall?.copyWith(color: theme.hintColor),
384
+
),
408
385
),
409
-
itemCount: _images.length,
410
-
itemBuilder: (context, index) {
411
-
final galleryImage = _images[index];
412
-
return Stack(
413
-
children: [
414
-
Positioned.fill(
415
-
child: Container(
416
-
decoration: BoxDecoration(
417
-
color: theme.colorScheme.surfaceContainerHighest,
418
-
borderRadius: BorderRadius.circular(8),
419
-
),
420
-
child: ClipRRect(
421
-
borderRadius: BorderRadius.circular(8),
422
-
child: Image.file(
423
-
File(galleryImage.file.path),
424
-
fit: BoxFit.cover,
425
-
),
426
-
),
427
-
),
386
+
Row(
387
+
children: [
388
+
Expanded(
389
+
child: AppButton(
390
+
label: 'Add photos (${_images.length}/10)',
391
+
onPressed: _pickImages,
392
+
icon: AppIcons.photoLibrary,
393
+
variant: AppButtonVariant.primary,
394
+
height: 40,
395
+
fontSize: 15,
396
+
borderRadius: 6,
428
397
),
429
-
if (galleryImage.isExisting)
430
-
Positioned(
431
-
left: 2,
432
-
top: 2,
398
+
),
399
+
],
400
+
),
401
+
],
402
+
if (_images.isNotEmpty) ...[
403
+
const SizedBox(height: 16),
404
+
GridView.builder(
405
+
shrinkWrap: true,
406
+
physics: const NeverScrollableScrollPhysics(),
407
+
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
408
+
crossAxisCount: 3,
409
+
crossAxisSpacing: 8,
410
+
mainAxisSpacing: 8,
411
+
),
412
+
itemCount: _images.length,
413
+
itemBuilder: (context, index) {
414
+
final galleryImage = _images[index];
415
+
return Stack(
416
+
children: [
417
+
Positioned.fill(
433
418
child: Container(
434
-
padding: const EdgeInsets.all(2),
435
419
decoration: BoxDecoration(
436
-
color: theme.colorScheme.secondary.withOpacity(0.7),
437
-
borderRadius: BorderRadius.circular(4),
420
+
color: theme.colorScheme.surfaceContainerHighest,
421
+
borderRadius: BorderRadius.circular(8),
438
422
),
439
-
child: Icon(
440
-
AppIcons.checkCircle,
441
-
color: theme.colorScheme.onSecondary,
442
-
size: 16,
423
+
child: ClipRRect(
424
+
borderRadius: BorderRadius.circular(8),
425
+
child: Image.file(
426
+
File(galleryImage.file.path),
427
+
fit: BoxFit.cover,
428
+
),
443
429
),
444
430
),
445
431
),
446
-
Positioned(
447
-
top: 2,
448
-
right: 2,
449
-
child: GestureDetector(
450
-
onTap: () => _removeImage(index),
451
-
child: Container(
452
-
decoration: BoxDecoration(
453
-
color: Colors.grey.withOpacity(0.7),
454
-
shape: BoxShape.circle,
432
+
if (galleryImage.isExisting)
433
+
Positioned(
434
+
left: 2,
435
+
top: 2,
436
+
child: Container(
437
+
padding: const EdgeInsets.all(2),
438
+
decoration: BoxDecoration(
439
+
color: theme.colorScheme.secondary.withOpacity(0.7),
440
+
borderRadius: BorderRadius.circular(4),
441
+
),
442
+
child: Icon(
443
+
AppIcons.checkCircle,
444
+
color: theme.colorScheme.onSecondary,
445
+
size: 16,
446
+
),
455
447
),
456
-
padding: const EdgeInsets.all(4),
457
-
child: const Icon(
458
-
AppIcons.close,
459
-
color: Colors.white,
460
-
size: 20,
448
+
),
449
+
Positioned(
450
+
top: 2,
451
+
right: 2,
452
+
child: GestureDetector(
453
+
onTap: () => _removeImage(index),
454
+
child: Container(
455
+
decoration: BoxDecoration(
456
+
color: Colors.grey.withOpacity(0.7),
457
+
shape: BoxShape.circle,
458
+
),
459
+
padding: const EdgeInsets.all(4),
460
+
child: const Icon(
461
+
AppIcons.close,
462
+
color: Colors.white,
463
+
size: 20,
464
+
),
461
465
),
462
466
),
463
467
),
464
-
),
465
-
],
466
-
);
467
-
},
468
-
),
468
+
],
469
+
);
470
+
},
471
+
),
472
+
],
469
473
],
470
-
],
474
+
),
471
475
),
472
476
),
473
477
),
474
478
),
475
479
),
476
-
if (_showUploadOverlay && widget.gallery == null)
480
+
if (_showUploadOverlay && widget.gallery == null) ...[
477
481
UploadProgressOverlay(
478
482
images: _images.where((img) => !img.isExisting).toList(),
479
483
currentIndex: _currentUploadIndex,
480
484
progress: _currentUploadProgress,
481
485
visible: _showUploadOverlay,
482
486
),
487
+
],
483
488
],
484
489
);
485
490
}