refactored data providers with centralized cache resolution, unified UI using custom dialogs and bottom sheets, and enhanced network error handling for Dio and TLS errors
This commit is contained in:
@@ -2,14 +2,11 @@ import 'package:flutter/material.dart';
|
||||
import 'package:syncfusion_flutter_calendar/calendar.dart';
|
||||
|
||||
import '../data/arbitrary_appointment.dart';
|
||||
import '../data/calendar_layout.dart';
|
||||
import 'cross_painter.dart';
|
||||
|
||||
class AppointmentTile extends StatelessWidget {
|
||||
static const _radius = BorderRadius.all(Radius.circular(7));
|
||||
static const _titleFontSize = 15.0;
|
||||
static const _titleMinFontSize = 11.0;
|
||||
static const _bodyFontSize = 10.0;
|
||||
static const _bodyLineHeight = 1.15;
|
||||
|
||||
final Appointment appointment;
|
||||
final bool crossedOut;
|
||||
@@ -42,8 +39,8 @@ class AppointmentTile extends StatelessWidget {
|
||||
children: [
|
||||
_AdaptiveTitle(
|
||||
text: appointment.subject,
|
||||
fontSize: _titleFontSize,
|
||||
minFontSize: _titleMinFontSize,
|
||||
fontSize: kAppointmentTitleFontSize,
|
||||
minFontSize: kAppointmentTitleMinFontSize,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
if (isCustom) ...[
|
||||
@@ -53,8 +50,8 @@ class AppointmentTile extends StatelessWidget {
|
||||
padding: const EdgeInsets.only(top: 1),
|
||||
child: _WrappingBody(
|
||||
text: description,
|
||||
fontSize: _bodyFontSize,
|
||||
lineHeight: _bodyLineHeight,
|
||||
fontSize: kAppointmentBodyFontSize,
|
||||
lineHeight: kAppointmentBodyLineHeight,
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -63,7 +60,7 @@ class AppointmentTile extends StatelessWidget {
|
||||
.split('\n')
|
||||
.where((p) => p.isNotEmpty)
|
||||
.take(2))
|
||||
_ScaledLine(text: line, fontSize: _bodyFontSize),
|
||||
_ScaledLine(text: line, fontSize: kAppointmentBodyFontSize),
|
||||
],
|
||||
],
|
||||
),
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
part of '../custom_workweek_calendar.dart';
|
||||
|
||||
class _OutsideHoursStrip extends StatelessWidget {
|
||||
static const int _maxVisibleChips = 2;
|
||||
static const double _chipHeight = 22;
|
||||
static const double _chipSpacing = 3;
|
||||
static const double _verticalPadding = 3;
|
||||
|
||||
final DateTime weekStart;
|
||||
final List<Appointment> appointments;
|
||||
final double rulerWidth;
|
||||
@@ -28,17 +23,17 @@ class _OutsideHoursStrip extends StatelessWidget {
|
||||
|
||||
final theme = Theme.of(context);
|
||||
final maxChipsPerDay = outside
|
||||
.map((day) => day.length > _maxVisibleChips ? _maxVisibleChips : day.length)
|
||||
.map((day) => day.length > kOutsideChipsMaxVisible ? kOutsideChipsMaxVisible : day.length)
|
||||
.fold<int>(0, (m, c) => c > m ? c : m);
|
||||
final stripHeight = _verticalPadding * 2 +
|
||||
maxChipsPerDay * _chipHeight +
|
||||
(maxChipsPerDay > 1 ? (maxChipsPerDay - 1) * _chipSpacing : 0);
|
||||
final stripHeight = kOutsideStripVerticalPadding * 2 +
|
||||
maxChipsPerDay * kOutsideChipHeight +
|
||||
(maxChipsPerDay > 1 ? (maxChipsPerDay - 1) * kOutsideChipSpacing : 0);
|
||||
|
||||
return Container(
|
||||
color: theme.colorScheme.surfaceContainerLowest,
|
||||
padding: const EdgeInsets.symmetric(vertical: _verticalPadding),
|
||||
padding: const EdgeInsets.symmetric(vertical: kOutsideStripVerticalPadding),
|
||||
child: SizedBox(
|
||||
height: stripHeight - _verticalPadding * 2,
|
||||
height: stripHeight - kOutsideStripVerticalPadding * 2,
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
@@ -47,9 +42,6 @@ class _OutsideHoursStrip extends StatelessWidget {
|
||||
Expanded(
|
||||
child: _OutsideDayColumn(
|
||||
appointments: outside[d],
|
||||
maxVisible: _maxVisibleChips,
|
||||
chipHeight: _chipHeight,
|
||||
chipSpacing: _chipSpacing,
|
||||
onAppointmentTap: onAppointmentTap,
|
||||
isCrossedOut: isCrossedOut,
|
||||
),
|
||||
@@ -63,17 +55,11 @@ class _OutsideHoursStrip extends StatelessWidget {
|
||||
|
||||
class _OutsideDayColumn extends StatelessWidget {
|
||||
final List<Appointment> appointments;
|
||||
final int maxVisible;
|
||||
final double chipHeight;
|
||||
final double chipSpacing;
|
||||
final void Function(Appointment) onAppointmentTap;
|
||||
final bool Function(Appointment) isCrossedOut;
|
||||
|
||||
const _OutsideDayColumn({
|
||||
required this.appointments,
|
||||
required this.maxVisible,
|
||||
required this.chipHeight,
|
||||
required this.chipSpacing,
|
||||
required this.onAppointmentTap,
|
||||
required this.isCrossedOut,
|
||||
});
|
||||
@@ -132,11 +118,12 @@ class _OutsideDayColumn extends StatelessWidget {
|
||||
if (!aLike && bLike) return 1;
|
||||
return a.startTime.compareTo(b.startTime);
|
||||
});
|
||||
final visible = sorted.length <= maxVisible
|
||||
final visible = sorted.length <= kOutsideChipsMaxVisible
|
||||
? sorted
|
||||
: sorted.take(maxVisible - 1).toList();
|
||||
final overflow =
|
||||
sorted.length <= maxVisible ? const <Appointment>[] : sorted.skip(maxVisible - 1).toList();
|
||||
: sorted.take(kOutsideChipsMaxVisible - 1).toList();
|
||||
final overflow = sorted.length <= kOutsideChipsMaxVisible
|
||||
? const <Appointment>[]
|
||||
: sorted.skip(kOutsideChipsMaxVisible - 1).toList();
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 2),
|
||||
@@ -145,9 +132,9 @@ class _OutsideDayColumn extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
for (var i = 0; i < visible.length; i++) ...[
|
||||
if (i > 0) SizedBox(height: chipSpacing),
|
||||
if (i > 0) const SizedBox(height: kOutsideChipSpacing),
|
||||
SizedBox(
|
||||
height: chipHeight,
|
||||
height: kOutsideChipHeight,
|
||||
child: _OutsideChip(
|
||||
appointment: visible[i],
|
||||
onTap: () => onAppointmentTap(visible[i]),
|
||||
@@ -155,9 +142,9 @@ class _OutsideDayColumn extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
if (overflow.isNotEmpty) ...[
|
||||
SizedBox(height: chipSpacing),
|
||||
const SizedBox(height: kOutsideChipSpacing),
|
||||
SizedBox(
|
||||
height: chipHeight,
|
||||
height: kOutsideChipHeight,
|
||||
child: _OutsideOverflowChip(
|
||||
count: overflow.length,
|
||||
onTap: () => _showOverflow(context, overflow),
|
||||
|
||||
@@ -429,8 +429,7 @@ class _OverflowTile extends StatelessWidget {
|
||||
padding: const EdgeInsets.all(1),
|
||||
child: Stack(
|
||||
children: [
|
||||
// Card peeking out at the bottom — visual hint that more cards lie
|
||||
// underneath the visible one.
|
||||
// Stacked-cards effect: a darker layer peeks out below the front card.
|
||||
Positioned(
|
||||
top: 4,
|
||||
left: 2,
|
||||
@@ -443,7 +442,6 @@ class _OverflowTile extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
// Front card with the "+N" indicator.
|
||||
Positioned(
|
||||
top: 0,
|
||||
left: 0,
|
||||
|
||||
Reference in New Issue
Block a user