focus-flow/apps/focus_flow_flutter/lib/widgets/timeline/timeline_view.dart
pyr0ball c730c33569 feat(ui): wire timeline card Break up quick action
Extracts the break-up dialog into a shared widgets/dialogs library so
the task modal and timeline card quick actions reuse the same flow
instead of duplicating it, then wires a Break up icon through
TimelineView/TaskTimelineCard to the existing breakUpTask command path.

Closes: #14
2026-07-07 13:45:04 -07:00

90 lines
3 KiB
Dart

// SPDX-FileCopyrightText: 2026 FocusFlow contributors
// SPDX-License-Identifier: AGPL-3.0-only
/// Renders Timeline View pieces for the FocusFlow Flutter timeline.
library;
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:scheduler_core/scheduler_core.dart'
show ApplicationChildTaskDraft;
import '../../models/today_screen_models.dart';
import '../../theme/focus_flow_tokens.dart';
import 'task_timeline_card.dart';
import 'timeline_axis.dart';
import 'timeline_geometry.dart';
part 'timeline_view/timeline_card_placement.dart';
part 'timeline_view/timeline_scroll_behavior.dart';
part 'timeline_view/timeline_view_state.dart';
/// Scrollable compact timeline view for Today cards.
class TimelineView extends StatefulWidget {
/// Creates a timeline view.
const TimelineView({
required this.cards,
required this.range,
required this.onCardSelected,
this.onAddTask,
this.onCardCompleted,
this.onPushToNext,
this.onPushToTomorrow,
this.onPushToBacklog,
this.onBreakUpCard,
this.now,
this.scrollTargetCardId,
this.scrollRequest = 0,
this.scrollToNowRequest = 0,
super.key,
});
/// Cards to position on the timeline.
final List<TimelineCardModel> cards;
/// Visible range used to build the timeline geometry.
final TimelineRangeModel range;
/// Callback invoked when a card is selected.
final ValueChanged<TimelineCardModel> onCardSelected;
/// Callback invoked when the timeline context menu requests a new task.
final Future<void> Function()? onAddTask;
/// Callback invoked when a task card status control requests completion.
final ValueChanged<TimelineCardModel>? onCardCompleted;
/// Callback invoked when a task card requests Push to next.
final Future<void> Function(TimelineCardModel card)? onPushToNext;
/// Callback invoked when a task card requests Push to tomorrow.
final Future<void> Function(TimelineCardModel card)? onPushToTomorrow;
/// Callback invoked when a task card requests Push to backlog.
final Future<void> Function(TimelineCardModel card)? onPushToBacklog;
/// Callback invoked with drafted child tasks after a task card's Break up
/// action is confirmed.
final Future<void> Function(
TimelineCardModel card,
List<ApplicationChildTaskDraft> children,
)?
onBreakUpCard;
/// Clock used to center the initial scroll position.
final DateTime Function()? now;
/// Card id requested by another surface, such as the required banner.
final String? scrollTargetCardId;
/// Monotonic request number that allows repeated jumps to the same card.
final int scrollRequest;
/// Monotonic request number that allows repeated jumps to current time.
final int scrollToNowRequest;
/// Creates the mutable state object used by this stateful widget.
/// Flutter calls this once for each mounted widget instance before lifecycle callbacks and builds begin.
@override
State<TimelineView> createState() => _TimelineViewState();
}