/
siblun
/
ReadFlow
Обзор
Документация
Войти
/
siblun
/
ReadFlow
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
develop
lib/presentation/widgets/note_card.dart
126 строк
5 KB
siblun
Add docs
21 апр 2026, 16:13
21 апр 2026, 16:13
c40d018
Код
Авторство
О чём код?
import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import '../../domain/models/note_model.dart'; import '../theme/app_colors.dart'; import '../theme/app_typography.dart'; /// Карточка отображения краткого содержания заметки или цитаты. /// /// Функциональность: /// - **Умное превью**: Использует геттер [note.preview] для безопасного отображения /// текста (включая парсинг JSON-формата Quill Delta). /// - **Типизация**: Визуально разделяет обычные заметки и цитаты с помощью /// иконок и специфической типографики ([AppTypography.quote]). /// - **Метаданные**: Отображает местоположение (номер главы/страницы) в верхнем /// регистре и локализованную дату создания. /// - **Интерактив**: Поддерживает callback-функции для просмотра, редактирования и удаления. class NoteCard extends StatelessWidget { final Note note; final VoidCallback? onView; final VoidCallback? onEdit; final VoidCallback? onDelete; const NoteCard({ super.key, required this.note, this.onView, this.onEdit, this.onDelete, }); @override Widget build(BuildContext context) { final formattedDate = _formatDate(note.createdAt); return GestureDetector( onTap: onView, child: Container( margin: EdgeInsets.only(bottom: 16.h), padding: EdgeInsets.all(20.w), decoration: ShapeDecoration( color: AppColors.cardBackground, shape: RoundedRectangleBorder( side: BorderSide( width: 1.w, color: AppColors.accentSecondary.withValues(alpha: 0.1), ), borderRadius: BorderRadius.circular(16.r), ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ if (note.hasLocation) Container( padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 2.h), decoration: BoxDecoration( color: AppColors.surface.withValues(alpha: 0.3), borderRadius: BorderRadius.circular(4.r), ), child: Text( note.location!.toUpperCase(), style: AppTypography.label.copyWith( fontSize: 9.sp, fontWeight: FontWeight.w700, letterSpacing: 0.9, color: AppColors.textMain.withValues(alpha: 0.7), ), ), ), Text( formattedDate, style: AppTypography.bodyMedium.copyWith( fontSize: 11.sp, fontWeight: FontWeight.w500, color: AppColors.textMain.withValues(alpha: 0.4), ), ), ], ), SizedBox(height: 11.h), Text( note.preview, style: (note.isQuote ? AppTypography.quote : AppTypography.bodyMedium).copyWith( fontSize: 15.sp, height: 1.63, ), maxLines: 3, overflow: TextOverflow.ellipsis, ), if (note.isQuote) ...[ SizedBox(height: 8.h), Row( children: [ Icon(Icons.format_quote_rounded, size: 12.w, color: AppColors.primaryAction.withValues(alpha: 0.5), ), SizedBox(width: 4.w), Text( 'Цитата', style: AppTypography.label.copyWith( fontSize: 9.sp, color: AppColors.primaryAction.withValues(alpha: 0.7), ), ), ], ), ], ], ), ), ); } String _formatDate(DateTime date) { const months = [ 'янв.', 'фев.', 'мар.', 'апр.', 'май', 'июн.', 'июл.', 'авг.', 'сен.', 'окт.', 'ноя.', 'дек.' ]; return '${date.day} ${months[date.month - 1]}'; } }