-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement timeline calendar view. (#195)
* Implement timeline calender view * Fix typo * Fix lint and build * Fix lint * Mr changes * Mr changes --------- Co-authored-by: kaushik <[email protected]>
- Loading branch information
1 parent
5ec663c
commit 7ee7493
Showing
9 changed files
with
711 additions
and
146 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
133 changes: 133 additions & 0 deletions
133
app/lib/ui/flow/journey/calender/horizontal_calendar_view.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
import 'dart:math'; | ||
|
||
import 'package:flutter/material.dart'; | ||
import 'package:style/extenstions/context_extenstions.dart'; | ||
import 'package:style/extenstions/date_extenstions.dart'; | ||
import 'package:style/text/app_text_dart.dart'; | ||
import 'package:yourspace_flutter/domain/extenstions/date_formatter.dart'; | ||
import 'package:yourspace_flutter/ui/flow/journey/calender/three_page_scroller.dart'; | ||
|
||
class HorizontalCalendarView extends StatefulWidget { | ||
final DateTime weekStartDate; | ||
final DateTime selectedDate; | ||
final ValueChanged<int> onSwipeWeek; | ||
final void Function(DateTime date) onTap; | ||
|
||
const HorizontalCalendarView({ | ||
super.key, | ||
required this.weekStartDate, | ||
required this.selectedDate, | ||
required this.onSwipeWeek, | ||
required this.onTap, | ||
}); | ||
|
||
@override | ||
State<HorizontalCalendarView> createState() => _HorizontalCalendarViewState(); | ||
} | ||
|
||
class _HorizontalCalendarViewState extends State<HorizontalCalendarView> { | ||
@override | ||
Widget build(BuildContext context) { | ||
final previousWeekDate = | ||
widget.weekStartDate.subtract(const Duration(days: 7)); | ||
final nextWeekDate = widget.weekStartDate.add(const Duration(days: 7)); | ||
|
||
return Column( | ||
children: [ | ||
Padding( | ||
padding: const EdgeInsets.only(top: 12, bottom: 16), | ||
child: ThreePageScroller( | ||
current: _weekDays(startDate: widget.weekStartDate), | ||
previous: _weekDays(startDate: previousWeekDate), | ||
next: _weekDays(startDate: nextWeekDate), | ||
onPageChanged: (direction) => widget.onSwipeWeek(direction), | ||
), | ||
), | ||
Divider(thickness: 1, height: 1, color: context.colorScheme.outline) | ||
], | ||
); | ||
} | ||
|
||
Widget _weekDays({ | ||
required DateTime startDate, | ||
}) { | ||
final weekDays = <DateTime>[]; | ||
for (var i = 0; i < 7; i++) { | ||
weekDays.add(startDate.add(Duration(days: i))); | ||
} | ||
final isWeekAfter = weekDays.first.isAfter(DateTime.now()); | ||
|
||
return Padding( | ||
padding: const EdgeInsets.symmetric(horizontal: 8), | ||
child: Row( | ||
children: weekDays.map( | ||
(date) { | ||
return isWeekAfter | ||
? const SizedBox() | ||
: _weekDayItem(date: date, context: context); | ||
}, | ||
).toList(), | ||
), | ||
); | ||
} | ||
|
||
Widget _weekDayItem({required BuildContext context, required DateTime date}) { | ||
final bool isSelected = date.isSameDay(widget.selectedDate); | ||
final isDayAfter = date.isAfter(DateTime.now()); | ||
final textColor = isDayAfter | ||
? context.colorScheme.textDisabled | ||
: context.colorScheme.textPrimary; | ||
|
||
return Expanded( | ||
child: GestureDetector( | ||
onTap: () => widget.onTap(date), | ||
child: LayoutBuilder( | ||
builder: (context, constraints) { | ||
return Center( | ||
child: Container( | ||
padding: const EdgeInsets.symmetric(vertical: 6), | ||
width: [48, constraints.maxWidth].reduce(min).toDouble(), | ||
decoration: BoxDecoration( | ||
borderRadius: BorderRadius.circular(8), | ||
color: isSelected | ||
? context.colorScheme.primary | ||
: Colors.transparent, | ||
border: Border.all( | ||
color: (isSelected || !date.isToday) | ||
? Colors.transparent | ||
: context.colorScheme.containerLow, | ||
width: 1, | ||
), | ||
), | ||
child: Column( | ||
mainAxisSize: MainAxisSize.min, | ||
children: [ | ||
Text( | ||
date.format(context, DateFormatType.weekShort), | ||
style: AppTextStyle.caption.copyWith( | ||
color: isSelected | ||
? context.colorScheme.textInversePrimary | ||
: context.colorScheme.textDisabled, | ||
), | ||
textScaler: TextScaler.noScaling, | ||
), | ||
const SizedBox(height: 2), | ||
Text( | ||
date.day.toString(), | ||
style: AppTextStyle.bodyBold.copyWith( | ||
color: isSelected | ||
? context.colorScheme.textInversePrimary | ||
: textColor, | ||
), | ||
textScaler: TextScaler.noScaling, | ||
), | ||
], | ||
), | ||
), | ||
); | ||
}, | ||
), | ||
), | ||
); | ||
} | ||
} |
80 changes: 80 additions & 0 deletions
80
app/lib/ui/flow/journey/calender/horizontal_calendar_view_model.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import 'package:flutter_riverpod/flutter_riverpod.dart'; | ||
import 'package:freezed_annotation/freezed_annotation.dart'; | ||
import 'package:style/extenstions/date_extenstions.dart'; | ||
|
||
part 'horizontal_calendar_view_model.freezed.dart'; | ||
|
||
final horizontalCalendarViewStateProvider = StateNotifierProvider.autoDispose< | ||
HorizontalCalendarViewModel, CalendarViewState>((ref) { | ||
return HorizontalCalendarViewModel(); | ||
}); | ||
|
||
class HorizontalCalendarViewModel extends StateNotifier<CalendarViewState> { | ||
HorizontalCalendarViewModel() | ||
: super( | ||
CalendarViewState( | ||
weekStartDate: DateTime.now().startOfDay, | ||
selectedDate: DateTime.now().startOfDay, | ||
), | ||
) { | ||
setCurrentWeekStartDate(); | ||
} | ||
|
||
void setCurrentWeekStartDate() { | ||
final currentDate = state.selectedDate; | ||
// Monday | ||
final dayOfWeek = currentDate.weekday; | ||
final daysToSubtract = dayOfWeek == 1 ? 0 : dayOfWeek - 1; | ||
final currentWeekStartDate = | ||
currentDate.subtract(Duration(days: daysToSubtract)); | ||
state = state.copyWith(weekStartDate: currentWeekStartDate); | ||
} | ||
|
||
void onSwipeWeek(int direction) { | ||
final currentWeekStartDate = state.weekStartDate; | ||
final newWeekStartDate = | ||
currentWeekStartDate.add(Duration(days: direction * 7)); | ||
if (newWeekStartDate.isAfter(DateTime.now().startOfDay)) { | ||
return; | ||
} | ||
state = state.copyWith(weekStartDate: newWeekStartDate); | ||
setContainsToday(); | ||
} | ||
|
||
void setSelectedDate(DateTime? date, {bool isPickerDate = false}) { | ||
state = state.copyWith( | ||
selectedDate: date?.startOfDay ?? DateTime.now().startOfDay); | ||
if (isPickerDate && date != null) { | ||
onSelectDateFromDatePicker(date); | ||
} | ||
} | ||
|
||
void onSelectDateFromDatePicker(DateTime date) { | ||
state = state.copyWith(weekStartDate: date.startOfWeek); | ||
setContainsToday(); | ||
} | ||
|
||
void setContainsToday() { | ||
final DateTime today = DateTime.now(); | ||
final DateTime endOfWeek = state.weekStartDate.add(const Duration(days: 6)); | ||
|
||
final containsToday = | ||
today.isAfter(state.weekStartDate) && today.isBefore(endOfWeek); | ||
state = state.copyWith(containsToday: containsToday); | ||
} | ||
|
||
void goToToday() { | ||
setSelectedDate(DateTime.now()); | ||
setCurrentWeekStartDate(); | ||
setContainsToday(); | ||
} | ||
} | ||
|
||
@freezed | ||
class CalendarViewState with _$CalendarViewState { | ||
const factory CalendarViewState({ | ||
required DateTime selectedDate, | ||
required DateTime weekStartDate, | ||
@Default(true) bool containsToday, | ||
}) = _CalendarViewState; | ||
} |
Oops, something went wrong.