Skip to content

Commit

Permalink
✨ fixes issue #267. show 0 hr and 24 hr markers in timeline.
Browse files Browse the repository at this point in the history
  • Loading branch information
ParthBaraiya committed Jun 13, 2024
1 parent 76c5430 commit 0a94526
Show file tree
Hide file tree
Showing 16 changed files with 645 additions and 396 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# [2.0.0 - Unreleased]

- Adds flag `showEndHours` to show start and end time. [#267](https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/issues/267)
- Introduced 2 new typedefs `TimeLineTimeBuilder` and `TimeStringBuilder`.
### Breaking Changes
- Use `TimeLineTimeBuilder` instead of `DateWidgetBuilder` to show time widget in timer line for `WeekView` and `DayView`.
- User `TimeStringBuilder` instead of `StringProvider` to get the time string in time line for `WeekView` and `DayView`.

# [1.2.0 - 10 May 2024](https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/tree/1.2.0)

- Fixed issue when adding full-day events to WeekView, event is not display at correct date. [#259](https://github.com/SimformSolutionsPvtLtd/flutter_calendar_view/issues/259)
Expand Down
2 changes: 1 addition & 1 deletion example/ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1300;
LastUpgradeCheck = 1430;
ORGANIZATIONNAME = "";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1300"
LastUpgradeVersion = "1430"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
4 changes: 2 additions & 2 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ List<CalendarEventData> _events = [
date: _now,
title: "Project meeting",
description: "Today is project meeting.",
startTime: DateTime(_now.year, _now.month, _now.day, 18, 30),
endTime: DateTime(_now.year, _now.month, _now.day, 22),
startTime: DateTime(_now.year, _now.month, _now.day, 0, 0),
endTime: DateTime(_now.year, _now.month, _now.day, 4, 0),
),
CalendarEventData(
date: _now.add(Duration(days: 1)),
Expand Down
52 changes: 44 additions & 8 deletions example/lib/widgets/day_view_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ class DayViewWidget extends StatelessWidget {
startDuration: Duration(hours: 8),
showHalfHours: true,
heightPerMinute: 3,
timeLineBuilder: _timeLineBuilder,
// timeLineBuilder: _timeLineBuilder,
hourIndicatorSettings: HourIndicatorSettings(
color: Theme.of(context).dividerColor,
),
showQuarterHours: true,
onEventTap: (events, date) {
Navigator.of(context).push(
MaterialPageRoute(
Expand All @@ -48,22 +49,24 @@ class DayViewWidget extends StatelessWidget {
liveTimeIndicatorSettings: LiveTimeIndicatorSettings(
color: Colors.redAccent,
showBullet: false,
showTime: true,
showTimeBackgroundView: true,
showTime: false,
showTimeBackgroundView: false,
),
showEndHours: true,
showStartHours: true,
);
}

Widget _timeLineBuilder(DateTime date) {
if (date.minute != 0) {
Widget _timeLineBuilder(TimeOfDay time, DateTime _) {
if (time.minute != 0) {
return Stack(
clipBehavior: Clip.none,
children: [
Positioned.fill(
top: -8,
right: 8,
child: Text(
"${date.hour}:${date.minute}",
"${time.hour}:${time.minute}",
textAlign: TextAlign.right,
style: TextStyle(
color: Colors.black.withAlpha(50),
Expand All @@ -76,15 +79,48 @@ class DayViewWidget extends StatelessWidget {
);
}

final hour = ((date.hour - 1) % 12) + 1;
final hour = ((time.hour - 1) % 12) + 1;

if (time.hour == 0 && time.minute == 0) {
return Stack(
clipBehavior: Clip.none,
children: [
Positioned.fill(
top: -7,
right: 8,
child: Text(
"$hour ${time.hour ~/ 12 == 0 ? "am" : "pm"}",
textAlign: TextAlign.right,
),
),
],
);
}

if (time.hour == 24 && time.minute == 0) {
return Stack(
clipBehavior: Clip.none,
children: [
Positioned.fill(
top: -18,
right: 8,
child: Text(
"$hour ${time.hour ~/ 12 == 0 ? "am" : "pm"}",
textAlign: TextAlign.right,
),
),
],
);
}

return Stack(
clipBehavior: Clip.none,
children: [
Positioned.fill(
top: -8,
right: 8,
child: Text(
"$hour ${date.hour ~/ 12 == 0 ? "am" : "pm"}",
"$hour ${time.hour ~/ 12 == 0 ? "am" : "pm"}",
textAlign: TextAlign.right,
),
),
Expand Down
1 change: 0 additions & 1 deletion example/lib/widgets/event_provider.dart

This file was deleted.

82 changes: 51 additions & 31 deletions lib/src/components/_internal_components.dart
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ class TimeLine extends StatefulWidget {
final double timeLineOffset;

/// This will display time string in timeline.
final DateWidgetBuilder timeLineBuilder;
final TimeLineTimeBuilder timeLineBuilder;

/// Flag to display half hours.
final bool showHalfHours;
Expand All @@ -167,6 +167,14 @@ class TimeLine extends StatefulWidget {
/// This field will be used to set end hour for day and week view
final int endHour;

/// Defines if we need to display the 0 hr and 24 hr text in time line or not.
final bool showEndHours;

/// Defines if we need to display the 0 hr and 24 hr text in time line or not.
final bool showStartHours;

final EdgeInsets padding;

/// Time line to display time at left side of day or week view.
const TimeLine({
Key? key,
Expand All @@ -180,6 +188,9 @@ class TimeLine extends StatefulWidget {
this.showQuarterHours = false,
required this.liveTimeIndicatorSettings,
this.endHour = Constants.hoursADay,
required this.showEndHours,
required this.showStartHours,
required this.padding,
}) : super(key: key);

@override
Expand All @@ -196,24 +207,6 @@ class _TimeLineState extends State<TimeLine> {
_timer = Timer.periodic(Duration(seconds: 1), _onTick);
}

@override
void dispose() {
_timer.cancel();
super.dispose();
}

/// Creates an recursive call that runs every 1 seconds.
/// This will rebuild TimeLine every second. This will allow us
/// to show/hide time line when there is overlap with
/// live time line indicator in Week and Day view.
void _onTick(Timer? timer) {
final time = TimeOfDay.now();
if (time != _currentTime && mounted) {
_currentTime = time;
setState(() {});
}
}

@override
Widget build(BuildContext context) {
return ConstrainedBox(
Expand All @@ -226,24 +219,30 @@ class _TimeLineState extends State<TimeLine> {
),
child: Stack(
children: [
for (int i = widget.startHour + 1; i < widget.endHour; i++)
for (int i = widget.startHour + (widget.showStartHours ? 0 : 1);
i < widget.endHour + (widget.showEndHours ? 1 : 0);
i++)
_timelinePositioned(
topPosition: widget.hourHeight * (i - widget.startHour) -
widget.timeLineOffset,
widget.timeLineOffset +
widget.padding.top,
bottomPosition: widget.height -
(widget.hourHeight * (i - widget.startHour + 1)) +
widget.timeLineOffset,
widget.timeLineOffset -
widget.padding.bottom,
hour: i,
),
if (widget.showHalfHours)
for (int i = widget.startHour; i < widget.endHour; i++)
_timelinePositioned(
topPosition: widget.hourHeight * (i - widget.startHour) -
widget.timeLineOffset +
widget._halfHourHeight,
widget._halfHourHeight +
widget.padding.top,
bottomPosition: widget.height -
(widget.hourHeight * (i - widget.startHour + 1)) +
widget.timeLineOffset,
widget.timeLineOffset -
widget.padding.bottom,
hour: i,
minutes: 30,
),
Expand All @@ -253,10 +252,12 @@ class _TimeLineState extends State<TimeLine> {
_timelinePositioned(
topPosition: widget.hourHeight * i -
widget.timeLineOffset +
widget.hourHeight * 0.25,
widget.hourHeight * 0.25 +
widget.padding.top,
bottomPosition: widget.height -
(widget.hourHeight * (i + 1)) +
widget.timeLineOffset,
widget.timeLineOffset -
widget.padding.bottom,
hour: i,
minutes: 15,
),
Expand All @@ -265,10 +266,12 @@ class _TimeLineState extends State<TimeLine> {
_timelinePositioned(
topPosition: widget.hourHeight * i -
widget.timeLineOffset +
widget.hourHeight * 0.75,
widget.hourHeight * 0.75 +
widget.padding.top,
bottomPosition: widget.height -
(widget.hourHeight * (i + 1)) +
widget.timeLineOffset,
widget.timeLineOffset -
widget.padding.bottom,
hour: i,
minutes: 45,
),
Expand All @@ -278,6 +281,24 @@ class _TimeLineState extends State<TimeLine> {
);
}

@override
void dispose() {
_timer.cancel();
super.dispose();
}

/// Creates an recursive call that runs every 1 seconds.
/// This will rebuild TimeLine every second. This will allow us
/// to show/hide time line when there is overlap with
/// live time line indicator in Week and Day view.
void _onTick(Timer? timer) {
final time = TimeOfDay.now();
if (time != _currentTime && mounted) {
_currentTime = time;
setState(() {});
}
}

/// To avoid overlap of live time line indicator, show time line when
/// current min is less than 45 min and is previous hour or
/// current min is greater than 15 min and is current hour
Expand All @@ -297,16 +318,15 @@ class _TimeLineState extends State<TimeLine> {
left: 0,
right: 0,
bottom: bottomPosition,
child: Container(
child: SizedBox(
height: widget.hourHeight,
width: widget.timeLineWidth,
child: widget.timeLineBuilder.call(
TimeOfDay(hour: hour, minute: minutes),
DateTime(
TimeLine._date.year,
TimeLine._date.month,
TimeLine._date.day,
hour,
minutes,
),
),
),
Expand Down
12 changes: 8 additions & 4 deletions lib/src/components/common_components.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import 'package:flutter/material.dart';

import '../calendar_event_data.dart';
import '../constants.dart';
import '../enumerations.dart';
import '../extensions.dart';
import '../style/header_style.dart';
import '../typedefs.dart';
import '../enumerations.dart';
import 'components.dart';

class CalendarPageHeader extends StatelessWidget {
Expand Down Expand Up @@ -134,6 +134,8 @@ class DefaultPressDetector extends StatelessWidget {
this.onDateTap,
this.onDateLongPress,
this.startHour = 0,
required this.padding,
required this.endHour,
});

final DateTime date;
Expand All @@ -144,11 +146,13 @@ class DefaultPressDetector extends StatelessWidget {
final DateTapCallback? onDateTap;
final DatePressCallback? onDateLongPress;
final int startHour;
final int endHour;
final EdgeInsets padding;

@override
Widget build(BuildContext context) {
final heightPerSlot = minuteSlotSize.minutes * heightPerMinute;
final slots = (Constants.hoursADay * 60) ~/ minuteSlotSize.minutes;
final slots = ((endHour - startHour) * 60) ~/ minuteSlotSize.minutes;

return SizedBox(
height: height,
Expand All @@ -157,10 +161,10 @@ class DefaultPressDetector extends StatelessWidget {
children: [
for (int i = 0; i < slots; i++)
Positioned(
top: heightPerSlot * i,
top: padding.top + heightPerSlot * i,
left: 0,
right: 0,
bottom: height - (heightPerSlot * (i + 1)),
bottom: height - (heightPerSlot * (i + 1)) - padding.bottom,
child: GestureDetector(
behavior: HitTestBehavior.translucent,
onLongPress: () => onDateLongPress?.call(
Expand Down
Loading

0 comments on commit 0a94526

Please sign in to comment.