Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Multiple language support and 24-hour format support #82

Merged
merged 8 commits into from
Jun 19, 2021
Merged
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ Some date/time-related parameters also have special suffixes:
* `timeOfDay`: A `Duration` between zero and 24 hours.
* `dayOfWeek`: An `int` between one and seven ([`DateTime.monday`](https://api.flutter.dev/flutter/dart-core/DateTime/monday-constant.html) through [`DateTime.sunday`](https://api.flutter.dev/flutter/dart-core/DateTime/sunday-constant.html)).

Timetable currently offers localizations for English and German.
Timetable currently offers localizations for English, German, Japanese and Chinese.
Even if you're just supporting English in your app, you have to add Timetable's localization delegate to your `MaterialApp`/`CupertinoApp`/`WidgetsApp`:

```dart
Expand Down
6 changes: 6 additions & 0 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@ class _TimetableExampleState extends State<TimetableExample>
// lineColor: Colors.green,
// shape: TriangleNowIndicatorShape(color: Colors.green),
// ),
// timeIndicatorStyleProvider: (time) => TimeIndicatorStyle(
// context,
// time,
// alwaysUse24HourFormat: false,
// ),
),
);
}
Expand All @@ -139,6 +144,7 @@ class _TimetableExampleState extends State<TimetableExample>
setState(() => _draggedEvents.removeWhere((it) => it.id == event.id));
_showSnackBar('Dragged event to $dateTime.');
},
onDragCanceled: (isMoved) => _showSnackBar('Your finger moved: $isMoved'),
child: BasicEventWidget(
event,
onTap: () => _showSnackBar('Part-day event $event tapped'),
Expand Down
8 changes: 7 additions & 1 deletion example/lib/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@ import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:timetable/timetable.dart';

final _mediaOverrideState = ValueNotifier(MediaOverrideState());
final _supportedLocales = [const Locale('de'), const Locale('en')];
final _supportedLocales = [
const Locale('de'),
const Locale('en'),
const Locale('ja'),
const Locale('zh', 'CN'),
const Locale('zh', 'TW'),
];

void initDebugOverlay() {
// https://pub.dev/packages/debug_overlay
Expand Down
36 changes: 24 additions & 12 deletions lib/src/components/multi_date_content.dart
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ class PartDayDraggableEvent extends StatefulWidget {
this.onDragStart,
this.onDragUpdate,
this.onDragEnd,
this.onDragCanceled,
required this.child,
Widget? childWhileDragging,
}) : childWhileDragging =
Expand All @@ -128,6 +129,11 @@ class PartDayDraggableEvent extends StatefulWidget {
/// their finger at all.
final void Function(DateTime?)? onDragEnd;

/// Called when a drag gesture is canceled.
///
/// The [bool] indicates whether the user moved their finger or not.
final void Function(bool isMoved)? onDragCanceled;

final Widget child;
final Widget childWhileDragging;

Expand All @@ -137,25 +143,31 @@ class PartDayDraggableEvent extends StatefulWidget {

class _PartDayDraggableEventState extends State<PartDayDraggableEvent> {
DateTime? _lastDragDateTime;
var _isMoved = false;

@override
Widget build(BuildContext context) {
return LongPressDraggable<_DragData>(
data: _DragData(),
maxSimultaneousDrags: 1,
onDragStarted: widget.onDragStart,
onDragUpdate: widget.onDragUpdate != null
? (details) {
_lastDragDateTime =
_DragInfos.resolveOffset(context, details.globalPosition);
widget.onDragUpdate!(_lastDragDateTime!);
}
: null,
onDragEnd: widget.onDragEnd != null
? (details) {
widget.onDragEnd!(_lastDragDateTime!);
_lastDragDateTime = null;
}
onDragUpdate: (details) {
if (widget.onDragUpdate != null) {
_lastDragDateTime =
_DragInfos.resolveOffset(context, details.globalPosition);
widget.onDragUpdate!(_lastDragDateTime!);
}
_isMoved = true;
},
onDragEnd: (details) {
if (widget.onDragEnd != null) {
widget.onDragEnd!(_lastDragDateTime);
_lastDragDateTime = null;
}
_isMoved = false;
},
onDraggableCanceled: widget.onDragCanceled != null
? (_, __) => widget.onDragCanceled!(_isMoved)
: null,
child: widget.child,
childWhenDragging: widget.childWhileDragging,
Expand Down
5 changes: 4 additions & 1 deletion lib/src/components/time_indicator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class TimeIndicatorStyle {
Duration time, {
TextStyle? textStyle,
String? label,
bool alwaysUse24HourFormat = true,
}) {
assert(time.isValidTimetableTimeOfDay);

Expand All @@ -87,7 +88,9 @@ class TimeIndicatorStyle {
label: label ??
() {
context.dependOnTimetableLocalizations();
return TimeIndicator.formatHour(time);
return alwaysUse24HourFormat
? TimeIndicator.formatHour24(time)
: TimeIndicator.formatHour(time);
}(),
);
}
Expand Down
64 changes: 64 additions & 0 deletions lib/src/localization.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import 'week.dart';
///
/// * `de` –German
/// * `en` – English
/// * `ja` – Japanese
/// * `zh_CN` – Chinese(Simplified)
/// * `zh_TW` – Chinese(Traditional)
///
/// By default, this delegate also configures [Intl] whenever Flutter's locale
/// changes. This behavior can be disabled via [setIntlLocale].
Expand Down Expand Up @@ -41,6 +44,13 @@ class TimetableLocalizationsDelegate
return const TimetableLocalizationDe();
case 'en':
return const TimetableLocalizationEn();
case 'ja':
return const TimetableLocalizationJa();
case 'zh':
if (locale.countryCode?.toLowerCase() == 'tw') {
return const TimetableLocalizationZhTw();
}
return const TimetableLocalizationZhCn();
default:
return null;
}
Expand Down Expand Up @@ -145,3 +155,57 @@ class TimetableLocalizationEn extends TimetableLocalizations {
String weekOfYear(Week week) =>
'Week ${week.weekOfYear}, ${week.weekBasedYear}';
}

class TimetableLocalizationJa extends TimetableLocalizations {
const TimetableLocalizationJa();

@override
List<String> weekLabels(Week week) {
return [
weekOfYear(week),
'第${week.weekOfYear}週',
'${week.weekOfYear}週',
'${week.weekOfYear}',
];
}

@override
String weekOfYear(Week week) =>
'Week ${week.weekOfYear}, ${week.weekBasedYear}';
}

class TimetableLocalizationZhCn extends TimetableLocalizations {
const TimetableLocalizationZhCn();

@override
List<String> weekLabels(Week week) {
return [
weekOfYear(week),
'第${week.weekOfYear}周',
'${week.weekOfYear}周',
'${week.weekOfYear}',
];
}

@override
String weekOfYear(Week week) =>
'Week ${week.weekOfYear}, ${week.weekBasedYear}';
}

class TimetableLocalizationZhTw extends TimetableLocalizations {
const TimetableLocalizationZhTw();

@override
List<String> weekLabels(Week week) {
return [
weekOfYear(week),
'第${week.weekOfYear}週',
'${week.weekOfYear}週',
'${week.weekOfYear}',
];
}

@override
String weekOfYear(Week week) =>
'Week ${week.weekOfYear}, ${week.weekBasedYear}';
}