Sitelet https://github.com/DNsoul/time_diary
Skip to content

Repository files navigation

time_diary

Персональный дневник времени: трекер активности и дневник мыслей в одном приложении.

CI License: MIT Flutter

Pet project. Делаю для себя, в свободное время. Без roadmap'а на годы, без обещаний обратной совместимости, без поддержки в трекере. Если что-то полезно — забирайте; если что-то сломалось — pull request приветствуется, но ответ может прийти когда придёт.

Главный экран: таймер от конца последней записи

Главный экран. Таймер идёт от конца последней зафиксированной записи — без старт/стоп.


Идея

Большинство трекеров времени требуют запускать таймер вручную. Я постоянно забывал — и переставал ими пользоваться через неделю.

time_diary устроен иначе: таймер идёт всегда. Он считается налету как now − endOfLastRecord. Когда фиксируешь блок — выбираешь активность и (опционально) добавляешь мысль/заметку. Сценарий «зафиксировать блок без заметки» занимает секунды.

Это превращает трекер времени в дневник: каждый блок — это и время, и контекст того, что в нём происходило.


Платформы

  • Android — работает.
  • iOS — в планах.

Возможности

  • Таймер без старт/стоп. Идёт от конца последней записи; сбрасывается только фиксацией нового блока.
  • Фиксация в два тапа. Активность + опциональная заметка.
  • Активности. Создание, редактирование, архивация. Цвет и иконка на каждую.
  • Привычки. Цели по длительности или количеству, периодичность (день/неделя/месяц/год), направление (atLeast/atMost), дни недели, стрики.
  • Статистика. День / неделя / месяц / год; круговые диаграммы, графики, факты по активности.
  • Дневник. Заметки из блоков агрегируются в отдельную ленту.
  • PIN на дневник. SHA-256 + случайная соль, кулдаун после трёх неверных попыток.
  • Локальные уведомления. Напоминания + persistent-таймер с тихими часами.
  • Темы и акценты. Кастомизируемый акцентный цвет, анимированный фон главного экрана.
  • Локализация. Русский, английский (через slang).
  • Offline-first. Drift как source of truth; Firestore — необязательный sync.
  • Sign-in. Google (Android).
  • Экспорт. JSON-дамп всех данных в один файл.
  • Сброс. Локальный (без потери облака) и облачный (без потери локального).

Скриншоты

Фиксация записи
Фиксация записи.
Активность, время, мысль.
Создание активности
Активность.
Иконка и цвет.
Статистика
Статистика.
Распределение времени по активностям.
Детали активности
Детали активности.
Динамика, тренды, факты.
Настройки
Настройки.
Sync, темы, PIN, уведомления.

Стек

Слой Что используется
UI Flutter (Dart ^3.11.4)
State management flutter_bloc (Cubit), get_it для DI
Навигация auto_route
Локальная БД drift + drift_flutter
Облако firebase_core, firebase_auth, cloud_firestore
Auth google_sign_in, sign_in_with_apple
i18n slang + slang_flutter
Уведомления flutter_local_notifications + timezone
Графики fl_chart
Тесты flutter_test, mocktail

Архитектура

Modified Clean Architecture без канонических UseCase. Бизнес-логика живёт в интеракторах.

flowchart LR
    UI["UI<br/>Widget / Screen"] <-->|state| Cubit
    Cubit --> Interactor["Interactor<br/>бизнес-правила"]
    Interactor --> Repo["Repository"]
    Repo <-->|streams| Local[("Drift<br/>source of truth")]
    Repo -.->|incremental sync| Remote[("Firestore<br/>опционально")]
Loading
  • LocalDataSource — Drift; для чтения возвращает Stream.
  • RemoteDataSource — Firestore. Используется только из Repository.
  • Repository — оркестрирует источники, остаётся в рамках одной сущности.
  • Interactor — может зависеть от нескольких Repository, содержит бизнес-правила.
  • Cubit — знает только про Interactor.
  • UI подписан на Cubit, не ходит в Data/Domain напрямую.

Подробнее — docs/architecture.md.

Структура проекта

lib/
  core/          # config, DI, router, theme, notifications, shared widgets
  data/
    database/    # Drift tables/DAOs
    datasources/ # local + remote
    repositories/
  domain/
    entities/    # Activity, TimeBlock, Habit, AppSettings, AuthUser
    interactors/ # бизнес-правила
    models/      # value objects
    utils/
  presentation/
    activity/  auth/  habits/  home/  main_tabs/
    record/    settings/  stats/  sync/  widgets/
  i18n/          # slang JSON + сгенерированные файлы

test/
  domain/interactors/  # unit-тесты бизнес-логики
  helpers/             # test doubles, фабрики
  widget_test.dart     # smoke

Инварианты

Несколько правил, которые держит сам домен (а не UI):

  • Записи не пересекаются по времени — гарантирует TimeBlockInteractor.
  • Запись через полночь автоматически делится на части по дням; note крепится к последней.
  • Удаление записи оставляет «дыру» — соседи не растягиваются.
  • Активность с записями нельзя удалить, только архивировать.
  • Таймер нельзя поставить на паузу. Сбрасывается только фиксацией нового блока.
  • Offline-first: Drift — source of truth; Firestore — дополнительный слой.

Полный список — docs/product.md.


Запуск

Требования

  • Flutter SDK через fvm (версия пиннится автоматически).
  • Android Studio для нативных билдов.
  • Firebase-проект, если нужен sync (опционально).

Шаги

# Зависимости
fvm flutter pub get

# Кодогенерация (Drift, AutoRoute, slang)
fvm dart run build_runner build --delete-conflicting-outputs

# Запуск
fvm flutter run

Firebase (опционально)

Без Firebase приложение работает в полностью offline-режиме — sync и облачный sign-in недоступны, остальное на месте.

Для включения sync:

  1. Создать Firebase-проект, добавить Android и iOS apps.
  2. Положить google-services.json в android/app/.
  3. Положить GoogleService-Info.plist в Xcode target Runner.
  4. Заполнить config.local.json (см. docs/sync.md).

Тесты

fvm flutter test

Юнит-тесты интеракторов лежат в test/domain/interactors/. Моки репозиториев — через mocktail. Smoke widget-тест проверяет, что shell с 4 табами строится и Home рисуется.

Принципы качества тестов в проекте описаны в docs/tooling.md — короткая выжимка: тестируем поведение, а не реализацию; специфичные ассерты вместо throwsArgumentError; границы вместо середин интервалов; полный детерминизм (никаких DateTime.now() в тестах).


Документация

Внутренняя документация для разработки — в docs/:

About

Дневник непрерывного учета времени: приложение, в котором таймер никогда не останавливается, а каждый отмеченный блок является одновременно записью о времени и мыслью.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages