diff --git a/lib/app/changelog.dart b/lib/app/changelog.dart index ba581f6..1587c43 100644 --- a/lib/app/changelog.dart +++ b/lib/app/changelog.dart @@ -1,4 +1,17 @@ const lunarisChangelog = [ + LunarisChange( + version: '3.0.0', + title: 'Lunaris 3.0 — Глобальное обновление: Дизайн 2.0, Интеграция Pawchive и умная синхронизация', + bullets: [ + 'Дизайн 2.0 (Modern Booru Experience): обновлённый современный интерфейс в стиле Material 3, адаптивные сетки галереи (Masonry / Staggered), улучшенная типографика и плавные микроанимации.', + 'Полноэкранный видеоплеер нового поколения: умный автоматический поворот экрана в ландшафтную ориентацию для горизонтальных видео и быстрый ручной переключатель ориентации в одно касание.', + 'Новая архитектура поиска (OverlayPortal): подсказки тегов отображаются через нативный портал Flutter без блокировки кнопок панели, очистки и сброса фильтров.', + 'Pawchive 2.0 & Двусторонняя синхронизация: подключение аккаунтов через логин/пароль или Session Cookie, импорт избранного с сервера, экспорт локальных коллекций в аккаунт на сервере и сквозная синхронизация со всех поддерживаемых платформ.', + 'Ленивое автоопределение разрешения: фоновый декодер автоматически рассчитывает и выводит точные размеры медиа (например, 1920 × 1080) для постов Pawchive без серверных метаданных.', + 'Умные per-ABI обновления: автообновление через Gitea скачивает точный APK под архитектуру вашего процессора (arm64-v8a, armeabi-v7a, x86_64), сокращая вес загрузки.', + 'Исправление вёрстки: устранены переносы текста в заголовке окна аккаунтов и карточках пользователей на экранах смартфонов.', + ], + ), LunarisChange( version: '2.3.10', title: 'Выгрузка локального избранного в Pawchive и двусторонняя синхронизация', diff --git a/lib/features/artists/presentation/widgets/pawchive_accounts_sheet.dart b/lib/features/artists/presentation/widgets/pawchive_accounts_sheet.dart index 290610c..aafd395 100644 --- a/lib/features/artists/presentation/widgets/pawchive_accounts_sheet.dart +++ b/lib/features/artists/presentation/widgets/pawchive_accounts_sheet.dart @@ -466,7 +466,7 @@ class _PawchiveAccountsSheetState extends ConsumerState ), // Header Padding( - padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 8), + padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10), child: Row( children: [ Container( @@ -488,31 +488,39 @@ class _PawchiveAccountsSheetState extends ConsumerState children: [ Text( 'Аккаунты Pawchive', - style: theme.textTheme.titleLarge?.copyWith( + style: theme.textTheme.titleMedium?.copyWith( fontWeight: FontWeight.bold, + fontSize: 18, ), + maxLines: 1, + overflow: TextOverflow.ellipsis, ), Text( 'Синхронизация авторов и избранного', style: theme.textTheme.bodySmall?.copyWith( color: scheme.onSurfaceVariant, + fontSize: 12, ), + maxLines: 1, + overflow: TextOverflow.ellipsis, ), ], ), ), - if (accounts.isNotEmpty) - FilledButton.tonalIcon( + if (accounts.isNotEmpty) ...[ + const SizedBox(width: 8), + IconButton.filledTonal( onPressed: _syncingAll ? null : _syncAllAccounts, icon: _syncingAll ? const SizedBox( - width: 16, - height: 16, + width: 18, + height: 18, child: CircularProgressIndicator(strokeWidth: 2), ) - : const Icon(Icons.sync_rounded, size: 18), - label: const Text('Синхронизировать'), + : const Icon(Icons.sync_rounded, size: 20), + tooltip: 'Синхронизировать все аккаунты', ), + ], ], ), ), @@ -806,7 +814,7 @@ class _PawchiveAccountsSheetState extends ConsumerState ), ), child: ListTile( - contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4), + contentPadding: const EdgeInsets.symmetric(horizontal: 14, vertical: 2), leading: CircleAvatar( backgroundColor: acc.isActive ? scheme.primary : scheme.surfaceContainerHighest, foregroundColor: acc.isActive ? scheme.onPrimary : scheme.onSurfaceVariant, @@ -817,48 +825,55 @@ class _PawchiveAccountsSheetState extends ConsumerState ), title: Row( children: [ - Expanded( + Flexible( child: Text( acc.username, - style: const TextStyle(fontWeight: FontWeight.bold), + style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 15), + maxLines: 1, + overflow: TextOverflow.ellipsis, ), ), - if (acc.isActive) + if (acc.isActive) ...[ + const SizedBox(width: 8), Container( - padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 2), + padding: const EdgeInsets.symmetric(horizontal: 7, vertical: 2), decoration: BoxDecoration( - color: scheme.primary, - borderRadius: BorderRadius.circular(10), + color: scheme.primary.withValues(alpha: 0.18), + borderRadius: BorderRadius.circular(8), ), child: Text( 'Активен', style: TextStyle( - color: scheme.onPrimary, - fontSize: 11, + color: scheme.primary, + fontSize: 10, fontWeight: FontWeight.bold, ), ), ), + ], ], ), - subtitle: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox(height: 2), - Text( - 'Авторов: ${acc.syncedArtistsCount} • ${acc.lastSyncedAt != null ? _formatDate(acc.lastSyncedAt!) : "не синхр."}', - style: TextStyle(color: scheme.onSurfaceVariant, fontSize: 12), - ), - ], + subtitle: Padding( + padding: const EdgeInsets.only(top: 2), + child: Text( + 'Авторов: ${acc.syncedArtistsCount} • ${acc.lastSyncedAt != null ? _formatDate(acc.lastSyncedAt!) : "не синхр."}', + style: TextStyle(color: scheme.onSurfaceVariant, fontSize: 12), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), ), trailing: Row( mainAxisSize: MainAxisSize.min, children: [ IconButton( + visualDensity: VisualDensity.compact, + constraints: const BoxConstraints(minWidth: 32, minHeight: 32), + padding: const EdgeInsets.all(6), + iconSize: 18, icon: isPushing ? const SizedBox( - width: 18, - height: 18, + width: 14, + height: 14, child: CircularProgressIndicator(strokeWidth: 2), ) : const Icon(Icons.cloud_upload_outlined), @@ -866,10 +881,14 @@ class _PawchiveAccountsSheetState extends ConsumerState onPressed: isBusy ? null : () => _pushFavoritesToAccount(acc), ), IconButton( + visualDensity: VisualDensity.compact, + constraints: const BoxConstraints(minWidth: 32, minHeight: 32), + padding: const EdgeInsets.all(6), + iconSize: 18, icon: isSyncing ? const SizedBox( - width: 18, - height: 18, + width: 14, + height: 14, child: CircularProgressIndicator(strokeWidth: 2), ) : const Icon(Icons.sync_rounded), @@ -877,6 +896,9 @@ class _PawchiveAccountsSheetState extends ConsumerState onPressed: isBusy ? null : () => _syncSingleAccount(acc), ), PopupMenuButton( + padding: EdgeInsets.zero, + constraints: const BoxConstraints(minWidth: 28, minHeight: 32), + iconSize: 18, icon: const Icon(Icons.more_vert_rounded), onSelected: (val) { if (val == 'active') { diff --git a/pubspec.yaml b/pubspec.yaml index f840e4d..1a41191 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: gel_rule_app description: Local backend/core layer for a Flutter booru browser app. publish_to: "none" -version: 2.3.10+50 +version: 3.0.0+51 environment: sdk: ">=3.3.0 <4.0.0"