Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import 'package:appflowy/generated/flowy_svgs.g.dart';
import 'package:appflowy/plugins/database/application/cell/bloc/date_cell_bloc.dart';
import 'package:appflowy/plugins/database/application/cell/cell_controller.dart';
import 'package:appflowy/plugins/database/application/cell/cell_controller_builder.dart';
import 'package:appflowy/plugins/database/application/database_controller.dart';
import 'package:appflowy/plugins/database/application/cell/bloc/date_cell_bloc.dart';
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
Expand Down Expand Up @@ -57,6 +57,10 @@ class _DateCellState extends State<DateCardCell> {
return const SizedBox.shrink();
}

final timeRemaining = getTimeRemainingFromCellData(state.cellData);
final isOverdue = state.cellData.dateTime != null &&
state.cellData.dateTime!.isBefore(DateTime.now());

return Container(
alignment: Alignment.centerLeft,
padding: widget.style.padding,
Expand All @@ -73,6 +77,19 @@ class _DateCellState extends State<DateCardCell> {
const HSpace(4),
const FlowySvg(FlowySvgs.clock_alarm_s),
],
if (timeRemaining.isNotEmpty) ...[
const HSpace(8),
Text(
timeRemaining,
style: widget.style.textStyle.copyWith(
fontSize: 11,
color: isOverdue
? Colors.red.shade600
: (widget.style.textStyle.color ?? Colors.grey)
.withValues(alpha: 0.6),
),
),
],
],
),
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,40 @@ String getDateCellStrFromCellData(FieldInfo field, DateCellData cellData) {
}
}

/// Returns a human-readable string representing the time remaining until the given date
/// or how long overdue it is
/// e.g., "3 days left", "2 hours left", "5 minutes left" (for future dates)
/// "2 days overdue", "3 hours overdue" (for past dates)
/// Returns an empty string if cellData.dateTime is null
String getTimeRemainingFromCellData(DateCellData cellData) {
if (cellData.dateTime == null) {
return "";
}

final now = DateTime.now();
final targetDate = cellData.dateTime!;
final difference = targetDate.difference(now);

// Calculate absolute time difference
final absDifference = difference.abs();
final days = absDifference.inDays;
final hours = absDifference.inHours;
final minutes = absDifference.inMinutes;

// Determine if it's overdue or upcoming
final isOverdue = difference.isNegative;

if (days > 0) {
return "$days day${days == 1 ? '' : 's'} ${isOverdue ? 'overdue' : 'left'}";
} else if (hours > 0) {
return "$hours hour${hours == 1 ? '' : 's'} ${isOverdue ? 'overdue' : 'left'}";
} else if (minutes > 0) {
return "$minutes min${minutes == 1 ? '' : 's'} ${isOverdue ? 'overdue' : 'left'}";
} else {
return isOverdue ? "Overdue" : "Less than a minute";
}
}

extension GetDateFormatExtension on DateFormatPB {
String get pattern => switch (this) {
DateFormatPB.Local => 'MM/dd/y',
Expand Down
Loading