Fliin
On this page

Screens / lists

Tasks

Groups tasks into overdue, today, upcoming, undated and done, each with its checkbox, with a quick add line and a sheet to edit the due day and priority.

16 of 16 variants pass
Tasks, list state
Platform
Brightness
Text scale
Direction

Import

Tasks is part of Fliin Pro. With a license key, sign in once with fliin login, then add it in a Flutter app where fliin init has run:

fliin login
fliin add tasks

Also installs: alert, app-bar, button, core, date-field, empty-state, field, link-button, page, section-header, segmented, separator, sheet, skeleton, surface, task-row, text, text-field, time-field

Examples

List

The task list loaded from the service: what is overdue, today and later, each task ticked off in place. standalone holds its own controller over the service you pass; the sample day keeps the example stable.

Tasks, list state
import 'package:your_app/ui/fliin/screens/tasks/tasks_controller.dart';
import 'package:your_app/ui/fliin/screens/tasks/tasks_data.dart';
import 'package:your_app/ui/fliin/screens/tasks/tasks_screen.dart';
import 'package:flutter/widgets.dart';

class TasksListExample extends StatelessWidget {
  const TasksListExample({super.key});

  static final _today = DateTime(2026, 10, 27);

  @override
  Widget build(BuildContext context) {
    return TasksScreen.standalone(
      service: SampleTasksService(today: _today, latency: const Duration(milliseconds: 600)),
      initial: TasksShown(sampleTasks(_today)),
      now: () => DateTime(2026, 10, 27, 10),
      onBack: () {},
    );
  }
}

Adding

Two tasks being added: one is on its way, the server refused the other, and a notice says so with a way to try again. standalone holds its own controller over the service you pass; the sample day keeps the example stable.

Tasks, adding state
import 'package:your_app/ui/fliin/screens/tasks/tasks_controller.dart';
import 'package:your_app/ui/fliin/screens/tasks/tasks_data.dart';
import 'package:your_app/ui/fliin/screens/tasks/tasks_screen.dart';
import 'package:flutter/widgets.dart';

class TasksAddingExample extends StatelessWidget {
  const TasksAddingExample({super.key});

  static final _today = DateTime(2026, 10, 27);

  @override
  Widget build(BuildContext context) {
    return TasksScreen.standalone(
      service: SampleTasksService(today: _today, latency: const Duration(milliseconds: 600)),
      initial: TasksShown(
        sampleTasks(_today),
        adding: const [
          TaskAdd(TaskDraft(key: 'k1', title: 'Buy bread')),
          TaskAdd(TaskDraft(key: 'k2', title: 'Call the bank'), failed: true),
        ],
        notice: const TasksNotice(TasksNoticeKind.addFailed, 'Call the bank'),
      ),
      now: () => DateTime(2026, 10, 27, 10),
      onBack: () {},
    );
  }
}

Deleted

A task just deleted: it stays crossed out with an undo until the deletion goes to the service. standalone holds its own controller over the service you pass; the sample day keeps the example stable.

Tasks, deleted state
import 'package:your_app/ui/fliin/screens/tasks/tasks_controller.dart';
import 'package:your_app/ui/fliin/screens/tasks/tasks_data.dart';
import 'package:your_app/ui/fliin/screens/tasks/tasks_screen.dart';
import 'package:flutter/widgets.dart';

class TasksDeletedExample extends StatelessWidget {
  const TasksDeletedExample({super.key});

  static final _today = DateTime(2026, 10, 27);

  @override
  Widget build(BuildContext context) {
    return TasksScreen.standalone(
      service: SampleTasksService(today: _today, latency: Duration.zero),
      initial: TasksShown(sampleTasks(_today), removed: const {'t3': TaskRemoval(undoable: true)}),
      now: () => DateTime(2026, 10, 27, 10),
      onBack: () {},
    );
  }
}

Save failed

A tick the server could not save: the task goes back and a notice says which one. standalone holds its own controller over the service you pass; the sample day keeps the example stable.

Tasks, save-failed state
import 'package:your_app/ui/fliin/screens/tasks/tasks_controller.dart';
import 'package:your_app/ui/fliin/screens/tasks/tasks_data.dart';
import 'package:your_app/ui/fliin/screens/tasks/tasks_screen.dart';
import 'package:flutter/widgets.dart';

class TasksSaveFailedExample extends StatelessWidget {
  const TasksSaveFailedExample({super.key});

  static final _today = DateTime(2026, 10, 27);

  @override
  Widget build(BuildContext context) {
    return TasksScreen.standalone(
      service: SampleTasksService(today: _today, latency: const Duration(milliseconds: 600)),
      initial: TasksShown(sampleTasks(_today), notice: const TasksNotice(TasksNoticeKind.doneFailed, 'Pay the rent')),
      now: () => DateTime(2026, 10, 27, 10),
      onBack: () {},
    );
  }
}

Empty

No task yet: the screen invites to add the first one. standalone holds its own controller over the service you pass; the sample day keeps the example stable.

Tasks, empty state
import 'package:your_app/ui/fliin/screens/tasks/tasks_controller.dart';
import 'package:your_app/ui/fliin/screens/tasks/tasks_data.dart';
import 'package:your_app/ui/fliin/screens/tasks/tasks_screen.dart';
import 'package:flutter/widgets.dart';

class TasksEmptyExample extends StatelessWidget {
  const TasksEmptyExample({super.key});

  static final _today = DateTime(2026, 10, 27);

  @override
  Widget build(BuildContext context) {
    return TasksScreen.standalone(
      service: SampleTasksService(today: _today, latency: const Duration(milliseconds: 600)),
      initial: const TasksShown([]),
      now: () => DateTime(2026, 10, 27, 10),
      onBack: () {},
    );
  }
}

Loading

While the service answers, placeholders keep the shape of the list. standalone holds its own controller over the service you pass; the sample day keeps the example stable.

Tasks, loading state
import 'package:your_app/ui/fliin/screens/tasks/tasks_controller.dart';
import 'package:your_app/ui/fliin/screens/tasks/tasks_data.dart';
import 'package:your_app/ui/fliin/screens/tasks/tasks_screen.dart';
import 'package:flutter/widgets.dart';

class TasksLoadingExample extends StatelessWidget {
  const TasksLoadingExample({super.key});

  static final _today = DateTime(2026, 10, 27);

  @override
  Widget build(BuildContext context) {
    return TasksScreen.standalone(
      service: SampleTasksService(today: _today, latency: const Duration(milliseconds: 600)),
      initial: const TasksLoading(),
      now: () => DateTime(2026, 10, 27, 10),
      onBack: () {},
    );
  }
}

Error

When loading fails, the screen says so and offers to try again. standalone holds its own controller over the service you pass; the sample day keeps the example stable.

Tasks, error state
import 'package:your_app/ui/fliin/screens/tasks/tasks_controller.dart';
import 'package:your_app/ui/fliin/screens/tasks/tasks_data.dart';
import 'package:your_app/ui/fliin/screens/tasks/tasks_screen.dart';
import 'package:flutter/widgets.dart';

class TasksErrorExample extends StatelessWidget {
  const TasksErrorExample({super.key});

  static final _today = DateTime(2026, 10, 27);

  @override
  Widget build(BuildContext context) {
    return TasksScreen.standalone(
      service: SampleTasksService(today: _today, latency: const Duration(milliseconds: 600)),
      initial: const TasksFailed(),
      now: () => DateTime(2026, 10, 27, 10),
      onBack: () {},
    );
  }
}

Offline

Without a connection, the screen asks to reconnect rather than showing an error. standalone holds its own controller over the service you pass; the sample day keeps the example stable.

Tasks, offline state
import 'package:your_app/ui/fliin/screens/tasks/tasks_controller.dart';
import 'package:your_app/ui/fliin/screens/tasks/tasks_data.dart';
import 'package:your_app/ui/fliin/screens/tasks/tasks_screen.dart';
import 'package:flutter/widgets.dart';

class TasksOfflineExample extends StatelessWidget {
  const TasksOfflineExample({super.key});

  static final _today = DateTime(2026, 10, 27);

  @override
  Widget build(BuildContext context) {
    return TasksScreen.standalone(
      service: SampleTasksService(today: _today, latency: const Duration(milliseconds: 600)),
      initial: const TasksOffline(),
      now: () => DateTime(2026, 10, 27, 10),
      onBack: () {},
    );
  }
}

Project

A project's list: title names it, header shows its progress above the sections, and showDone: false lets a checked task leave the screen.

Tasks, project state
import 'package:your_app/ui/fliin/components/progress/fl_progress.dart';
import 'package:your_app/ui/fliin/components/text/fl_text.dart';
import 'package:your_app/ui/fliin/core/fliin.dart';
import 'package:your_app/ui/fliin/screens/tasks/tasks_controller.dart';
import 'package:your_app/ui/fliin/screens/tasks/tasks_data.dart';
import 'package:your_app/ui/fliin/screens/tasks/tasks_screen.dart';
import 'package:flutter/widgets.dart';

class TasksProjectExample extends StatelessWidget {
  const TasksProjectExample({super.key});

  static final _today = DateTime(2026, 10, 27);

  @override
  Widget build(BuildContext context) {
    final tasks = sampleTasks(_today);
    final done = tasks.where((task) => task.done).length;
    final space = FlScope.of(context).space;
    return TasksScreen.standalone(
      service: SampleTasksService(today: _today, latency: const Duration(milliseconds: 600)),
      initial: TasksShown(tasks),
      now: () => DateTime(2026, 10, 27, 10),
      title: 'Moving house',
      showDone: false,
      header: Padding(
        padding: EdgeInsetsDirectional.fromSTEB(space.lg, space.sm, space.lg, space.sm),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          spacing: space.sm,
          children: [
            FlText('$done of ${tasks.length} done', type: FlTextType.bodySm, tone: FlTextTone.muted),
            FlProgress.linear(value: done / tasks.length, label: 'Progress'),
          ],
        ),
      ),
      onBack: () {},
    );
  }
}

Routing

fliin add tasks prints the route for the router it finds in your pubspec, a file next to the page that wires its navigation. Each of them:

go_router

// lib/tasks_route.dart, next to tasks_page.dart.
import 'package:go_router/go_router.dart';

import 'tasks_page.dart';

/// Add tasksRoute to the routes of your GoRouter.
final tasksRoute = GoRoute(
  path: '/tasks',
  builder: (context, state) => TasksPage(
    // Alone in the stack (deep link, go): your app's home.
    onBack: () => context.canPop() ? context.pop() : context.go('/'),
  ),
);

navigator

// lib/tasks_route.dart, next to tasks_page.dart.
import 'package:flutter/material.dart';

import 'tasks_page.dart';

/// Opens “Tasks”: `Navigator.of(context).push(tasksRoute())`.
Route<void> tasksRoute() => MaterialPageRoute<void>(
  builder: (context) => TasksPage(
    onBack: () => Navigator.of(context).maybePop(),
  ),
);

State

The controller is a ChangeNotifier from widgets.dart, with no package. fliin add tasks prints the page that holds it with the state management it finds, its imports written for your package; below they read your_app. Your backend implements the Service interface of the screen's _data.dart file:

none

// lib/tasks_page.dart
// Your backend: implement TasksService (tasks_data.dart) and pass it instead of the sample service.
import 'package:your_app/ui/fliin/screens/tasks/tasks_data.dart';
import 'package:your_app/ui/fliin/screens/tasks/tasks_screen.dart';
import 'package:flutter/widgets.dart';

/// A single sample service for the whole app: what you check, add or
/// delete stays from one opening of the screen to the next.
final sampleTasksService = SampleTasksService(today: DateTime.now());

class TasksPage extends StatelessWidget {
  const TasksPage({
    super.key,
    required this.onBack,
  });

  final VoidCallback onBack;

  @override
  Widget build(BuildContext context) => TasksScreen.standalone(
    service: sampleTasksService,
    onBack: onBack,
  );
}

provider

// lib/tasks_page.dart
// Your backend: implement TasksService (tasks_data.dart) and pass it instead of the sample service.
import 'package:your_app/ui/fliin/screens/tasks/tasks_controller.dart';
import 'package:your_app/ui/fliin/screens/tasks/tasks_data.dart';
import 'package:your_app/ui/fliin/screens/tasks/tasks_screen.dart';
import 'package:flutter/widgets.dart';
import 'package:provider/provider.dart';

/// A single sample service for the whole app: what you check, add or
/// delete stays from one opening of the screen to the next.
final sampleTasksService = SampleTasksService(today: DateTime.now());

class TasksPage extends StatelessWidget {
  const TasksPage({
    super.key,
    required this.onBack,
  });

  final VoidCallback onBack;

  @override
  Widget build(BuildContext context) => ChangeNotifierProvider(
    create: (_) => TasksController(service: sampleTasksService)..load(),
    child: Builder(
      builder: (context) => TasksScreen(
        controller: context.read<TasksController>(),
        onBack: onBack,
      ),
    ),
  );
}

riverpod

// lib/tasks_page.dart
// Your backend: implement TasksService (tasks_data.dart) and pass it instead of the sample service.
import 'package:your_app/ui/fliin/screens/tasks/tasks_controller.dart';
import 'package:your_app/ui/fliin/screens/tasks/tasks_data.dart';
import 'package:your_app/ui/fliin/screens/tasks/tasks_screen.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

/// A single sample service for the whole app: what you check, add or
/// delete stays from one opening of the screen to the next.
final sampleTasksService = SampleTasksService(today: DateTime.now());

final tasksControllerProvider = Provider.autoDispose<TasksController>((ref) {
  final controller = TasksController(service: sampleTasksService)..load();
  ref.onDispose(controller.dispose);
  return controller;
});

class TasksPage extends ConsumerWidget {
  const TasksPage({
    super.key,
    required this.onBack,
  });

  final VoidCallback onBack;

  @override
  Widget build(BuildContext context, WidgetRef ref) => TasksScreen(
    controller: ref.watch(tasksControllerProvider),
    onBack: onBack,
  );
}

bloc

// lib/tasks_page.dart
// Your backend: implement TasksService (tasks_data.dart) and pass it instead of the sample service.
import 'package:your_app/ui/fliin/screens/tasks/tasks_controller.dart';
import 'package:your_app/ui/fliin/screens/tasks/tasks_data.dart';
import 'package:your_app/ui/fliin/screens/tasks/tasks_screen.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

/// A single sample service for the whole app: what you check, add or
/// delete stays from one opening of the screen to the next.
final sampleTasksService = SampleTasksService(today: DateTime.now());

/// The screen's controller as a bloc, for your BlocListener and BlocBuilder:
/// one emission per controller notification. `version` tells them apart
/// when `state` does not change (mode, filters, text…, read them on
/// `controller`). The screen listens to the controller itself.
class TasksCubit extends Cubit<({TasksState state, int version})> {
  TasksCubit(this.controller) : super((state: controller.state, version: 0)) {
    controller.addListener(_changed);
  }

  final TasksController controller;

  void _changed() => emit((state: controller.state, version: state.version + 1));

  @override
  Future<void> close() {
    controller
      ..removeListener(_changed)
      ..dispose();
    return super.close();
  }
}

class TasksPage extends StatelessWidget {
  const TasksPage({
    super.key,
    required this.onBack,
  });

  final VoidCallback onBack;

  @override
  Widget build(BuildContext context) => BlocProvider(
    create: (_) => TasksCubit(TasksController(service: sampleTasksService)..load()),
    child: Builder(
      builder: (context) => TasksScreen(
        controller: context.read<TasksCubit>().controller,
        onBack: onBack,
      ),
    ),
  );
}

API

TasksScreen: class extends StatefulWidget
TasksScreen.new: const new({super.key, required TasksController controller, VoidCallback? onBack, DateTime Function() now, TasksDateFormat? formatDate, TasksTimeFormat? formatTime, String? title, bool showDone, Widget? header})
TasksScreen.standalone: const new({super.key, required TasksService service, TasksState? initial, VoidCallback? onBack, DateTime Function() now, TasksDateFormat? formatDate, TasksTimeFormat? formatTime, String? title, bool showDone, Widget? header})
TasksScreen.controller: get TasksController?
TasksScreen.service: get TasksService?
TasksScreen.initial: get TasksState?
TasksScreen.onBack: get VoidCallback?
TasksScreen.now: get DateTime Function()
TasksScreen.formatDate: get TasksDateFormat?
TasksScreen.formatTime: get TasksTimeFormat?
TasksScreen.title: get String?
TasksScreen.showDone: get bool
TasksScreen.header: get Widget?
TasksScreen.createState: State<TasksScreen>()
TasksState: sealed class permits {TasksFailed, TasksLoading, TasksOffline, TasksShown}
TasksState.new: const new()
TasksLoading: final class extends TasksState
TasksLoading.new: const new()
TasksFailed: final class extends TasksState
TasksFailed.new: const new()
TasksOffline: final class extends TasksState
TasksOffline.new: const new()
TaskRemoval: final class
TaskRemoval.new: const new({required bool undoable})
TaskRemoval.undoable: get bool
TaskAdd: final class
TaskAdd.new: const new(TaskDraft draft, {bool failed})
TaskAdd.draft: get TaskDraft
TaskAdd.failed: get bool
TasksNoticeKind: enum {doneFailed, addFailed, deleteFailed, refreshFailed, refreshOffline}
TasksNoticeKind.doneFailed: static final TasksNoticeKind
TasksNoticeKind.addFailed: static final TasksNoticeKind
TasksNoticeKind.deleteFailed: static final TasksNoticeKind
TasksNoticeKind.refreshFailed: static final TasksNoticeKind
TasksNoticeKind.refreshOffline: static final TasksNoticeKind
TasksNotice: final class
TasksNotice.new: const new(TasksNoticeKind kind, [String? title])
TasksNotice.kind: get TasksNoticeKind
TasksNotice.title: get String?
TasksShown: final class extends TasksState
TasksShown.new: const new(List<Task> tasks, {Map<String, TaskRemoval> removed, List<TaskAdd> adding, bool refreshing, TasksNotice? notice})
TasksShown.tasks: get List<Task>
TasksShown.removed: get Map<String, TaskRemoval>
TasksShown.adding: get List<TaskAdd>
TasksShown.refreshing: get bool
TasksShown.notice: get TasksNotice?
TasksShown.isEmpty: get bool
TaskSaveOutcome: enum {saved, offline, failed, missing}
TaskSaveOutcome.saved: static final TaskSaveOutcome
TaskSaveOutcome.offline: static final TaskSaveOutcome
TaskSaveOutcome.failed: static final TaskSaveOutcome
TaskSaveOutcome.missing: static final TaskSaveOutcome
TasksController: class extends ChangeNotifier
TasksController.new: new({required TasksService service, TasksState initial, Duration undoDelay, String Function()? newKey})
TasksController.service: get TasksService
TasksController.undoDelay: get Duration
TasksController.newKey: get String Function()
TasksController.state: get TasksState
TasksController.load: Future<void>()
TasksController.refresh: Future<void>()
TasksController.setDone: bool(String id, {required bool done})
TasksController.add: bool(String title)
TasksController.retryAdd: bool(String key)
TasksController.discardAdd: bool(String key)
TasksController.update: Future<TaskSaveOutcome>(String id, TaskEdit edit)
TasksController.delete: bool(String id)
TasksController.undo: bool(String id)
TasksController.dispose: void()
TaskDue: final class
TaskDue.new: new(DateTime day, {FlTime? time})
TaskDue.day: get DateTime
TaskDue.time: get FlTime?
TaskDue.operator ==: bool(Object other)
TaskDue.hashCode: get int
Task: final class
Task.new: const new({required String id, required String title, TaskDue? due, FlTaskPriority? priority, bool done})
Task.id: get String
Task.title: get String
Task.due: get TaskDue?
Task.priority: get FlTaskPriority?
Task.done: get bool
Task.withDone: Task(bool done)
Task.withEdit: Task(TaskEdit edit)
Task.operator ==: bool(Object other)
Task.hashCode: get int
TaskEdit: final class
TaskEdit.new: const new({required String title, TaskDue? due, FlTaskPriority? priority})
TaskEdit.title: get String
TaskEdit.due: get TaskDue?
TaskEdit.priority: get FlTaskPriority?
TaskDraft: final class
TaskDraft.new: const new({required String key, required String title})
TaskDraft.key: get String
TaskDraft.title: get String
TasksNoNetwork: final class implements Exception
TasksNoNetwork.new: const new()
TasksService: abstract interface class
TasksService.new: new()
TasksService.tasks: abstract Future<List<Task>>()
TasksService.add: abstract Future<Task>(TaskDraft draft)
TasksService.setDone: abstract Future<void>(String id, {required bool done})
TasksService.update: abstract Future<Task>(String id, TaskEdit edit)
TasksService.delete: abstract Future<void>(String id)
TaskSection: enum {overdue, today, upcoming, someday, done}
TaskSection.overdue: static final TaskSection
TaskSection.today: static final TaskSection
TaskSection.upcoming: static final TaskSection
TaskSection.someday: static final TaskSection
TaskSection.done: static final TaskSection
taskDueIsPast: bool(TaskDue due, DateTime now)
taskSectionOf: TaskSection(Task task, DateTime now)
groupTasks: List<(TaskSection, List<Task>)>(Iterable<Task> tasks, DateTime now)
sampleTasks: List<Task>(DateTime today)
SampleTasksService: final class implements TasksService
SampleTasksService.new: new({required DateTime today, List<Task>? tasks, Duration latency})
SampleTasksService.latency: get Duration
SampleTasksService.tasks: Future<List<Task>>()
SampleTasksService.add: Future<Task>(TaskDraft draft)
SampleTasksService.setDone: Future<void>(String id, {required bool done})
SampleTasksService.update: Future<Task>(String id, TaskEdit edit)
SampleTasksService.delete: Future<void>(String id)
TasksDateFormat: typedef = String Function(DateTime day, Locale locale)
TasksTimeFormat: typedef = String Function(FlTime time, Locale locale)
tasksL10n: const Map<String, Map<String, String>>
TasksStrings: final class
TasksStrings.new: const new(String language, {required DateTime now, TasksDateFormat? formatDate, TasksTimeFormat? formatTime})
TasksStrings.of: factory new(BuildContext context, {required DateTime now, TasksDateFormat? formatDate, TasksTimeFormat? formatTime})
TasksStrings.language: get String
TasksStrings.now: get DateTime
TasksStrings.formatDate: get TasksDateFormat?
TasksStrings.formatTime: get TasksTimeFormat?
TasksStrings.digits: String(int n)
TasksStrings.time: String(FlTime time)
TasksStrings.day: String(DateTime day)
TasksStrings.due: String(TaskDue due)
TasksStrings.separator: get String
TasksStrings.title: get String
TasksStrings.back: get String
TasksStrings.refresh: get String
TasksStrings.loading: get String
TasksStrings.section: String(TaskSection section, int count)
TasksStrings.overdue: get String
TasksStrings.priority: String(FlTaskPriority priority)
TasksStrings.priorityChoice: String(FlTaskPriority? priority)
TasksStrings.edit: String(String title)
TasksStrings.delete: String(String title)
TasksStrings.deleted: String(String title)
TasksStrings.undo: get String
TasksStrings.adding: get String
TasksStrings.notAdded: get String
TasksStrings.retry: get String
TasksStrings.retryAdd: String(String title)
TasksStrings.discard: get String
TasksStrings.discardAdd: String(String title)
TasksStrings.newLabel: get String
TasksStrings.newHint: get String
TasksStrings.add: get String
TasksStrings.added: String(String title)
TasksStrings.marked: String(String title, {required bool done})
TasksStrings.notice: String(TasksNoticeKind kind, String? title)
TasksStrings.emptyTitle: get String
TasksStrings.emptyMessage: get String
TasksStrings.errorTitle: get String
TasksStrings.errorMessage: get String
TasksStrings.offlineTitle: get String
TasksStrings.offlineMessage: get String
TasksStrings.retryLoad: get String
TasksStrings.editTitle: get String
TasksStrings.sheetLabel: get String
TasksStrings.sheetClose: get String
TasksStrings.sheetBarrier: get String
TasksStrings.fieldTitle: get String
TasksStrings.fieldTitleError: get String
TasksStrings.fieldDay: get String
TasksStrings.fieldTime: get String
TasksStrings.fieldTimeHelp: get String
TasksStrings.fieldPriority: get String
TasksStrings.save: get String
TasksStrings.deleteTask: get String
TasksStrings.saveOutcome: String(TaskSaveOutcome outcome)

Strings

Every label in English, French and Arabic. The screen follows the closest Localizations; the same table is in the manifest, ready for your ARB files.

Keyenfrar
tasksTitleTasksTâchesالمهام
tasksBackBackRetourرجوع
tasksRefreshRefresh the tasksActualiser les tâchesتحديث المهام
tasksLoadingLoading your tasksChargement des tâchesجارٍ تحميل المهام
tasksSectionOverdueOverdueEn retardمتأخرة
tasksSectionTodayTodayAujourd’huiاليوم
tasksSectionUpcomingUpcomingÀ venirالقادمة
tasksSectionSomedayNo due dateSans échéanceبلا موعد
tasksSectionDoneDoneFaitesالمنجزة
tasksSeparator, , ،
tasksSectionCount{section} · {count}{section} · {count}{section} · {count}
tasksOverdueOverdueEn retardمتأخرة
tasksTodayTodayAujourd’huiاليوم
tasksTomorrowTomorrowDemainغدًا
tasksYesterdayYesterdayHierأمس
tasksDate{weekday}, {month} {day}{weekday} {day} {month}{weekday} {day} {month}
tasksDateYear{month} {day}, {year}{day} {month} {year}{day} {month} {year}
tasksDueAt{day} · {time}{day} · {time}{day} · ⁦{time}⁩
tasksMonthsJanuary,February,March,April,May,June,July,August,September,October,November,Decemberjanvier,février,mars,avril,mai,juin,juillet,août,septembre,octobre,novembre,décembreيناير,فبراير,مارس,أبريل,مايو,يونيو,يوليو,أغسطس,سبتمبر,أكتوبر,نوفمبر,ديسمبر
tasksWeekdaysMonday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sundaylundi,mardi,mercredi,jeudi,vendredi,samedi,dimancheالاثنين,الثلاثاء,الأربعاء,الخميس,الجمعة,السبت,الأحد
tasksHours12truefalsefalse
tasksAmAMAMص
tasksPmPMPMم
tasksPriorityLowLow priorityPriorité basseأولوية منخفضة
tasksPriorityMediumMedium priorityPriorité moyenneأولوية متوسطة
tasksPriorityHighHigh priorityPriorité hauteأولوية عالية
tasksEditEdit “{title}”Modifier « {title} »تعديل «⁨{title}⁩»
tasksDeleteDelete “{title}”Supprimer « {title} »حذف «⁨{title}⁩»
tasksDeleted“{title}” deleted« {title} » suppriméeحُذفت «⁨{title}⁩»
tasksUndoUndoAnnulerتراجع
tasksAddingAdding…Ajout…جارٍ الإضافة…
tasksNotAddedNot addedNon ajoutéeلم تُضف
tasksRetryTry againRéessayerأعد المحاولة
tasksRetryAddTry adding “{title}” againRéessayer d’ajouter « {title} »أعد محاولة إضافة «⁨{title}⁩»
tasksDiscardRemoveRetirerإزالة
tasksDiscardAddRemove “{title}”Retirer « {title} »إزالة «⁨{title}⁩»
tasksNewLabelNew taskNouvelle tâcheمهمة جديدة
tasksNewHintWhat needs doing?Que faut-il faire ?ما الذي يجب إنجازه؟
tasksAddAddAjouterإضافة
tasksAdded“{title}” added« {title} » ajoutéeأُضيفت «⁨{title}⁩»
tasksMarkedDone“{title}” done« {title} » faiteأُنجزت «⁨{title}⁩»
tasksMarkedTodo“{title}” to do« {title} » à faire«⁨{title}⁩» غير منجزة
tasksDoneFailed“{title}” could not be saved. It is back as it was.« {title} » n’a pas pu être enregistrée. Elle est revenue comme avant.تعذّر حفظ «⁨{title}⁩». عادت كما كانت.
tasksAddFailed“{title}” could not be added.« {title} » n’a pas pu être ajoutée.تعذّرت إضافة «⁨{title}⁩».
tasksDeleteFailed“{title}” could not be deleted. It is back in the list.« {title} » n’a pas pu être supprimée. Elle est revenue dans la liste.تعذّر حذف «⁨{title}⁩». عادت إلى القائمة.
tasksRefreshFailedYour tasks could not refresh.Les tâches n’ont pas pu se mettre à jour.تعذّر تحديث المهام.
tasksRefreshOfflineYou are offline. The tasks shown may be out of date.Vous êtes hors ligne. Les tâches affichées ne sont peut-être pas à jour.أنت غير متصل. قد لا تكون المهام المعروضة محدّثة.
tasksEmptyTitleNothing to doRien à faireلا شيء لإنجازه
tasksEmptyMessageWrite your first task below.Écrivez votre première tâche ci-dessous.اكتب مهمتك الأولى أدناه.
tasksErrorTitleYour tasks could not loadImpossible de charger les tâchesتعذّر تحميل المهام
tasksErrorMessageTry again in a moment.Réessayez dans un instant.أعد المحاولة بعد قليل.
tasksOfflineTitleYou are offlineVous êtes hors ligneأنت غير متصل
tasksOfflineMessageConnect to see your tasks.Connectez-vous pour voir vos tâches.اتصل لعرض مهامك.
tasksEditTitleEdit taskModifier la tâcheتعديل المهمة
tasksSheetLabelEdit taskModifier la tâcheتعديل المهمة
tasksSheetCloseCloseFermerإغلاق
tasksSheetBarrierClose the editorFermer l’éditionإغلاق التعديل
tasksFieldTitleTitleTitreالعنوان
tasksFieldTitleErrorGive the task a title.Donnez un titre à la tâche.أعطِ المهمة عنوانًا.
tasksFieldDayDue dateÉchéanceتاريخ الاستحقاق
tasksFieldTimeTimeHeureالوقت
tasksFieldTimeHelpChoose a due date first.Choisissez d’abord une échéance.اختر تاريخ الاستحقاق أولًا.
tasksFieldPriorityPriorityPrioritéالأولوية
tasksPriorityNoneNoneAucuneبلا
tasksPriorityLowShortLowBasseمنخفضة
tasksPriorityMediumShortMediumMoyenneمتوسطة
tasksPriorityHighShortHighHauteعالية
tasksSaveSaveEnregistrerحفظ
tasksDeleteTaskDelete taskSupprimer la tâcheحذف المهمة
tasksSaveFailedThe task could not be saved. Try again.La tâche n’a pas pu être enregistrée. Réessayez.تعذّر حفظ المهمة. أعد المحاولة.
tasksSaveOfflineYou are offline. The task is unchanged.Vous êtes hors ligne. La tâche n’a pas changé.أنت غير متصل. لم تتغير المهمة.
tasksSaveMissingThis task no longer exists.Cette tâche n’existe plus.هذه المهمة لم تعد موجودة.
tasksRetryLoadTry againRéessayerأعد المحاولة

Reference renders

The 16 images published with version 0.2.5, rendered by the shared harness on macOS with Flutter 3.47.7. Each shows every state side by side, at the size of an iPhone (390 × 844) or of an Android phone (412 × 915). fliin verify tasks compares your copy to them.

iOS · Light
Tasks, iOS, Light, text 1.0×, Left to right
Text 1.0× · Left to right
Tasks, iOS, Light, text 1.0×, Right to left
Text 1.0× · Right to left
Tasks, iOS, Light, text 2.0×, Left to right
Text 2.0× · Left to right
Tasks, iOS, Light, text 2.0×, Right to left
Text 2.0× · Right to left
iOS · Dark
Tasks, iOS, Dark, text 1.0×, Left to right
Text 1.0× · Left to right
Tasks, iOS, Dark, text 1.0×, Right to left
Text 1.0× · Right to left
Tasks, iOS, Dark, text 2.0×, Left to right
Text 2.0× · Left to right
Tasks, iOS, Dark, text 2.0×, Right to left
Text 2.0× · Right to left
Android · Light
Tasks, Android, Light, text 1.0×, Left to right
Text 1.0× · Left to right
Tasks, Android, Light, text 1.0×, Right to left
Text 1.0× · Right to left
Tasks, Android, Light, text 2.0×, Left to right
Text 2.0× · Left to right
Tasks, Android, Light, text 2.0×, Right to left
Text 2.0× · Right to left
Android · Dark
Tasks, Android, Dark, text 1.0×, Left to right
Text 1.0× · Left to right
Tasks, Android, Dark, text 1.0×, Right to left
Text 1.0× · Right to left
Tasks, Android, Dark, text 2.0×, Left to right
Text 2.0× · Left to right
Tasks, Android, Dark, text 2.0×, Right to left
Text 2.0× · Right to left

Use it to

  • toggle a task between done and to do, saved afterwards
  • show overdue, today, upcoming and undated tasks in their own groups
  • add a new to-do quickly
  • edit when a task is due and how urgent it is
  • remove a task with a few seconds to bring it back
  • hide completed tasks in a folded group
  • show a to-do list screen with its sections and a field to add tasks
Not for
  • a single box in a form: use the checkbox (checkbox)
  • the events of a day or a week: use the agenda (agenda)
  • a single task to check off, with its due date and priority, placed elsewhere: use the task row (task-row)
States
  • List
  • Adding
  • Deleted
  • Save failed
  • Empty
  • Loading
  • Error
  • Offline

Arrows to move, Enter to open, Escape to close.