feat: Add support for reported pre-signed URLs in comments and daily progress report
This commit is contained in:
parent
5cf0202cc1
commit
916cfa3af4
@ -60,6 +60,7 @@ class _CommentTaskBottomSheetState extends State<CommentTaskBottomSheet>
|
||||
controller.basicValidator.getController('task_id')?.text =
|
||||
data['taskId'] ?? '';
|
||||
controller.basicValidator.getController('comment')?.clear();
|
||||
controller.basicValidator.getController('preSignedUrls')?.clear();
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (_scrollController.hasClients) {
|
||||
_scrollController.jumpTo(_scrollController.position.maxScrollExtent);
|
||||
@ -178,6 +179,90 @@ class _CommentTaskBottomSheetState extends State<CommentTaskBottomSheet>
|
||||
icon: Icons.done_all_outlined,
|
||||
),
|
||||
buildTeamMembers(),
|
||||
if ((widget.taskData['reportedPreSignedUrls']
|
||||
as List<dynamic>?)
|
||||
?.isNotEmpty ==
|
||||
true) ...[
|
||||
MySpacing.height(8),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 0.0),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Icon(Icons.image_outlined,
|
||||
size: 18, color: Colors.grey[700]),
|
||||
MySpacing.width(8),
|
||||
MyText.titleSmall(
|
||||
"Reported Images",
|
||||
fontWeight: 600,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
MySpacing.height(8),
|
||||
|
||||
Builder(
|
||||
builder: (context) {
|
||||
final allImageUrls = List<String>.from(
|
||||
widget.taskData['reportedPreSignedUrls'] ?? [],
|
||||
);
|
||||
|
||||
if (allImageUrls.isEmpty) return const SizedBox();
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal:
|
||||
16.0), // Same horizontal padding
|
||||
child: SizedBox(
|
||||
height: 70,
|
||||
child: ListView.separated(
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: allImageUrls.length,
|
||||
separatorBuilder: (_, __) =>
|
||||
const SizedBox(width: 12),
|
||||
itemBuilder: (context, index) {
|
||||
final url = allImageUrls[index];
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierColor: Colors.black54,
|
||||
builder: (_) => ImageViewerDialog(
|
||||
imageSources: allImageUrls,
|
||||
initialIndex: index,
|
||||
),
|
||||
);
|
||||
},
|
||||
child: ClipRRect(
|
||||
borderRadius:
|
||||
BorderRadius.circular(12),
|
||||
child: Image.network(
|
||||
url,
|
||||
width: 70,
|
||||
height: 70,
|
||||
fit: BoxFit.cover,
|
||||
errorBuilder:
|
||||
(context, error, stackTrace) =>
|
||||
Container(
|
||||
width: 70,
|
||||
height: 70,
|
||||
color: Colors.grey.shade200,
|
||||
child: Icon(Icons.broken_image,
|
||||
color: Colors.grey[600]),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
MySpacing.height(16),
|
||||
],
|
||||
Row(
|
||||
children: [
|
||||
Icon(Icons.comment_outlined,
|
||||
@ -456,17 +541,9 @@ class _CommentTaskBottomSheetState extends State<CommentTaskBottomSheet>
|
||||
comment['commentedBy'] ?? 'Unknown';
|
||||
final relativeTime =
|
||||
timeAgo(comment['date'] ?? '');
|
||||
|
||||
// Dummy image URLs (simulate as if coming from backend)
|
||||
final imageUrls = [
|
||||
'https://picsum.photos/seed/${index}a/100',
|
||||
'https://picsum.photos/seed/${index}b/100',
|
||||
'https://picsum.photos/seed/${index}a/100',
|
||||
'https://picsum.photos/seed/${index}b/100',
|
||||
'https://picsum.photos/seed/${index}a/100',
|
||||
'https://picsum.photos/seed/${index}b/100',
|
||||
];
|
||||
|
||||
final imageUrls = List<String>.from(
|
||||
comment['preSignedUrls'] ?? []);
|
||||
return Container(
|
||||
margin: const EdgeInsets.symmetric(
|
||||
vertical: 8), // Spacing between items
|
||||
|
@ -9,10 +9,11 @@ class TaskModel {
|
||||
final AssignedBy assignedBy;
|
||||
final List<TeamMember> teamMembers;
|
||||
final List<Comment> comments;
|
||||
final List<String> reportedPreSignedUrls;
|
||||
|
||||
TaskModel({
|
||||
required this.assignmentDate,
|
||||
this.reportedDate,
|
||||
this.reportedDate,
|
||||
required this.id,
|
||||
required this.workItem,
|
||||
required this.workItemId,
|
||||
@ -21,13 +22,14 @@ class TaskModel {
|
||||
required this.assignedBy,
|
||||
required this.teamMembers,
|
||||
required this.comments,
|
||||
required this.reportedPreSignedUrls,
|
||||
});
|
||||
|
||||
factory TaskModel.fromJson(Map<String, dynamic> json) {
|
||||
return TaskModel(
|
||||
assignmentDate: DateTime.parse(json['assignmentDate']),
|
||||
reportedDate: json['reportedDate'] != null
|
||||
? DateTime.tryParse(json['reportedDate'])
|
||||
? DateTime.tryParse(json['reportedDate'])
|
||||
: null,
|
||||
id: json['id'],
|
||||
workItem:
|
||||
@ -41,6 +43,10 @@ class TaskModel {
|
||||
.toList(),
|
||||
comments:
|
||||
(json['comments'] as List).map((e) => Comment.fromJson(e)).toList(),
|
||||
reportedPreSignedUrls: (json['reportedPreSignedUrls'] as List<dynamic>?)
|
||||
?.map((e) => e.toString())
|
||||
.toList() ??
|
||||
[],
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -51,6 +57,7 @@ class WorkItem {
|
||||
final WorkArea? workArea;
|
||||
final int? plannedWork;
|
||||
final int? completedWork;
|
||||
final List<String> preSignedUrls;
|
||||
|
||||
WorkItem({
|
||||
this.id,
|
||||
@ -58,6 +65,7 @@ class WorkItem {
|
||||
this.workArea,
|
||||
this.plannedWork,
|
||||
this.completedWork,
|
||||
this.preSignedUrls = const [],
|
||||
});
|
||||
|
||||
factory WorkItem.fromJson(Map<String, dynamic> json) {
|
||||
@ -70,6 +78,10 @@ class WorkItem {
|
||||
json['workArea'] != null ? WorkArea.fromJson(json['workArea']) : null,
|
||||
plannedWork: json['plannedWork'],
|
||||
completedWork: json['completedWork'],
|
||||
preSignedUrls: (json['preSignedUrls'] as List<dynamic>?)
|
||||
?.map((e) => e.toString())
|
||||
.toList() ??
|
||||
[],
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -167,11 +179,13 @@ class Comment {
|
||||
final String comment;
|
||||
final TeamMember commentedBy;
|
||||
final DateTime timestamp;
|
||||
final List<String> preSignedUrls;
|
||||
|
||||
Comment({
|
||||
required this.comment,
|
||||
required this.commentedBy,
|
||||
required this.timestamp,
|
||||
required this.preSignedUrls,
|
||||
});
|
||||
|
||||
factory Comment.fromJson(Map<String, dynamic> json) {
|
||||
@ -181,6 +195,10 @@ class Comment {
|
||||
? TeamMember.fromJson(json['employee'])
|
||||
: TeamMember(id: '', firstName: '', lastName: null),
|
||||
timestamp: DateTime.parse(json['commentDate'] ?? ''),
|
||||
preSignedUrls: (json['preSignedUrls'] as List<dynamic>?)
|
||||
?.map((e) => e.toString())
|
||||
.toList() ??
|
||||
[],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -607,8 +607,12 @@ class _DailyProgressReportScreenState extends State<DailyProgressReportScreen>
|
||||
'text': comment.comment,
|
||||
'date': isoDate,
|
||||
'commentedBy': commenterName,
|
||||
'preSignedUrls':
|
||||
comment.preSignedUrls,
|
||||
};
|
||||
}).toList();
|
||||
final taskLevelPreSignedUrls =
|
||||
task.reportedPreSignedUrls;
|
||||
|
||||
final taskData = {
|
||||
'activity': activityName,
|
||||
@ -622,6 +626,8 @@ class _DailyProgressReportScreenState extends State<DailyProgressReportScreen>
|
||||
'teamSize': task.teamMembers.length,
|
||||
'teamMembers': teamMembers,
|
||||
'taskComments': taskComments,
|
||||
'reportedPreSignedUrls':
|
||||
taskLevelPreSignedUrls,
|
||||
};
|
||||
|
||||
showModalBottomSheet(
|
||||
|
Loading…
x
Reference in New Issue
Block a user