界面优化

This commit is contained in:
DelLevin-Home
2026-07-04 19:44:23 +08:00
parent 337590b374
commit fab952a625
15 changed files with 155 additions and 79 deletions

View File

@@ -260,7 +260,8 @@ flutter pub get
```bash ```bash
# 构建 Release APK # 构建 Release APK
flutter build apk --release flutter build apk --release
# 推荐只 arm64-v8a
flutter build apk --release --target-platform android-arm64
# 构建 App BundleGoogle Play # 构建 App BundleGoogle Play
flutter build appbundle --release flutter build appbundle --release
``` ```

View File

@@ -192,6 +192,7 @@ class Book {
final String title; // 书籍名称 final String title; // 书籍名称
final String? coverPath; // 本地封面路径 final String? coverPath; // 本地封面路径
final List<String> authors; // 作者列表 final List<String> authors; // 作者列表
final List<String> translators; // 译者列表
final List<String> alternateTitles; // 别名 final List<String> alternateTitles; // 别名
final String? publisher; // 出版社 final String? publisher; // 出版社
final List<String> genres; // 类型 final List<String> genres; // 类型
@@ -212,6 +213,7 @@ class Book {
required this.title, required this.title,
this.coverPath, this.coverPath,
this.authors = const [], this.authors = const [],
this.translators = const [],
this.alternateTitles = const [], this.alternateTitles = const [],
this.publisher, this.publisher,
this.genres = const [], this.genres = const [],
@@ -234,6 +236,7 @@ class Book {
title: json['title'] ?? '', title: json['title'] ?? '',
coverPath: json['cover_path'], coverPath: json['cover_path'],
authors: Movie.parseStringList(json['authors']), authors: Movie.parseStringList(json['authors']),
translators: Movie.parseStringList(json['translators']),
alternateTitles: Movie.parseStringList(json['alternate_titles']), alternateTitles: Movie.parseStringList(json['alternate_titles']),
publisher: json['publisher'], publisher: json['publisher'],
genres: Movie.parseStringList(json['genres']), genres: Movie.parseStringList(json['genres']),
@@ -257,6 +260,7 @@ class Book {
'title': title, 'title': title,
'cover_path': coverPath, 'cover_path': coverPath,
'authors': jsonEncode(authors), 'authors': jsonEncode(authors),
'translators': jsonEncode(translators),
'alternate_titles': jsonEncode(alternateTitles), 'alternate_titles': jsonEncode(alternateTitles),
'publisher': publisher, 'publisher': publisher,
'genres': jsonEncode(genres), 'genres': jsonEncode(genres),
@@ -286,6 +290,7 @@ class Book {
String? title, String? title,
Object? coverPath = _copyWithNull, Object? coverPath = _copyWithNull,
List<String>? authors, List<String>? authors,
List<String>? translators,
List<String>? alternateTitles, List<String>? alternateTitles,
String? publisher, String? publisher,
List<String>? genres, List<String>? genres,
@@ -306,6 +311,7 @@ class Book {
title: title ?? this.title, title: title ?? this.title,
coverPath: coverPath is _CopyWithNullSentinel ? this.coverPath : (coverPath as String?), coverPath: coverPath is _CopyWithNullSentinel ? this.coverPath : (coverPath as String?),
authors: authors ?? this.authors, authors: authors ?? this.authors,
translators: translators ?? this.translators,
alternateTitles: alternateTitles ?? this.alternateTitles, alternateTitles: alternateTitles ?? this.alternateTitles,
publisher: publisher ?? this.publisher, publisher: publisher ?? this.publisher,
genres: genres ?? this.genres, genres: genres ?? this.genres,

View File

@@ -89,6 +89,7 @@ class _BookDetailPageState extends State<BookDetailPage> {
_buildBasicInfo(book), _buildBasicInfo(book),
Divider(height: 0.5, thickness: 0.5, color: colors.outline), Divider(height: 0.5, thickness: 0.5, color: colors.outline),
_buildAuthorsSection(book), _buildAuthorsSection(book),
if (book.translators.isNotEmpty) _buildTranslatorsSection(book),
if (book.genres.isNotEmpty) _buildGenresSection(book), if (book.genres.isNotEmpty) _buildGenresSection(book),
if (book.isbn != null && book.isbn!.isNotEmpty) _buildIsbnSection(book), if (book.isbn != null && book.isbn!.isNotEmpty) _buildIsbnSection(book),
if (book.publisher != null && book.publisher!.isNotEmpty) _buildPublisherSection(book), if (book.publisher != null && book.publisher!.isNotEmpty) _buildPublisherSection(book),
@@ -190,6 +191,7 @@ class _BookDetailPageState extends State<BookDetailPage> {
const SizedBox(height: 20), const SizedBox(height: 20),
// 信息区块:无毛玻璃 // 信息区块:无毛玻璃
_buildAuthorsSection(book), _buildAuthorsSection(book),
if (book.translators.isNotEmpty) _buildTranslatorsSection(book),
if (book.isbn != null && book.isbn!.isNotEmpty) _buildIsbnSection(book), if (book.isbn != null && book.isbn!.isNotEmpty) _buildIsbnSection(book),
if (book.publisher != null && book.publisher!.isNotEmpty) _buildPublisherSection(book), if (book.publisher != null && book.publisher!.isNotEmpty) _buildPublisherSection(book),
if (book.publishDate != null) _buildPublishDateSection(book), if (book.publishDate != null) _buildPublishDateSection(book),
@@ -764,6 +766,39 @@ class _BookDetailPageState extends State<BookDetailPage> {
); );
} }
Widget _buildTranslatorsSection(Book book) {
final isOverlay = _detailStyle == 1;
final colors = Theme.of(context).colorScheme;
return Padding(
padding: EdgeInsets.symmetric(horizontal: 24, vertical: isOverlay ? 5 : 16),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SizedBox(
width: 64,
child: Text(
'译者',
style: TextStyle(
fontSize: 13,
color: isOverlay ? const Color(0x66FFFFFF) : colors.onSurface.withValues(alpha: 0.4),
),
),
),
Expanded(
child: Text(
book.translators.join(''),
style: TextStyle(
fontSize: 15,
color: isOverlay ? Colors.white : colors.onSurface,
height: 1.5,
),
),
),
],
),
);
}
Widget _buildIsbnSection(Book book) { Widget _buildIsbnSection(Book book) {
final isOverlay = _detailStyle == 1; final isOverlay = _detailStyle == 1;
final colors = Theme.of(context).colorScheme; final colors = Theme.of(context).colorScheme;

View File

@@ -43,6 +43,7 @@ class _BookFormPageState extends State<BookFormPage> {
late TextEditingController _isbnController; late TextEditingController _isbnController;
List<String> _authors = []; List<String> _authors = [];
List<String> _translators = [];
List<String> _alternateTitles = []; List<String> _alternateTitles = [];
List<String> _genres = []; List<String> _genres = [];
String? _coverPath; String? _coverPath;
@@ -74,6 +75,7 @@ class _BookFormPageState extends State<BookFormPage> {
if (book != null) { if (book != null) {
_authors = List.from(book.authors); _authors = List.from(book.authors);
_translators = List.from(book.translators);
_alternateTitles = List.from(book.alternateTitles); _alternateTitles = List.from(book.alternateTitles);
_genres = List.from(book.genres); _genres = List.from(book.genres);
_coverPath = book.coverPath; _coverPath = book.coverPath;
@@ -165,7 +167,7 @@ class _BookFormPageState extends State<BookFormPage> {
}, },
), ),
// 作者 + 出版社 // 作者 + 译者
_halfCard('作者', _authors.isEmpty ? '' : '${_authors.length}人:${_authors.join('')}', Icons.person_outline, _halfCard('作者', _authors.isEmpty ? '' : '${_authors.length}人:${_authors.join('')}', Icons.person_outline,
onTap: () async { onTap: () async {
final provider = context.read<AppProvider>(); final provider = context.read<AppProvider>();
@@ -174,6 +176,14 @@ class _BookFormPageState extends State<BookFormPage> {
if (r != null) setState(() => _authors = r); if (r != null) setState(() => _authors = r);
}, },
), ),
_halfCard('译者', _translators.isEmpty ? '' : '${_translators.length}人:${_translators.join('')}', Icons.translate,
onTap: () async {
final provider = context.read<AppProvider>();
final data = provider.books.map((b) => b.translators).toList();
final r = await GenreSelectorPage.show(context: context, title: '选择译者', existingTagsFuture: compute(_collectUnique, data), initialSelected: _translators, hint: '如:李继宏、许钧');
if (r != null) setState(() => _translators = r);
},
),
_halfCard('出版社', _publisherController.text, Icons.business_outlined, _halfCard('出版社', _publisherController.text, Icons.business_outlined,
onTap: () async { onTap: () async {
final r = await TextInputPanel.show(context: context, title: '出版社', initialValue: _publisherController.text, hint: '请输入出版社'); final r = await TextInputPanel.show(context: context, title: '出版社', initialValue: _publisherController.text, hint: '请输入出版社');
@@ -572,7 +582,7 @@ class _BookFormPageState extends State<BookFormPage> {
if (_isbnController.text.trim().isNotEmpty) return true; if (_isbnController.text.trim().isNotEmpty) return true;
if (_publisherController.text.trim().isNotEmpty) return true; if (_publisherController.text.trim().isNotEmpty) return true;
if (_coverPath != null) return true; if (_coverPath != null) return true;
if (_authors.isNotEmpty || _alternateTitles.isNotEmpty || _genres.isNotEmpty) return true; if (_authors.isNotEmpty || _translators.isNotEmpty || _alternateTitles.isNotEmpty || _genres.isNotEmpty) return true;
if (_publishDate != null) return true; if (_publishDate != null) return true;
if (_startDate != null) return true; if (_startDate != null) return true;
if (_finishDate != null) return true; if (_finishDate != null) return true;
@@ -616,7 +626,7 @@ class _BookFormPageState extends State<BookFormPage> {
} }
final newBook = Book( final newBook = Book(
id: newBookId, title: _titleController.text.trim(), coverPath: finalCoverPath, id: newBookId, title: _titleController.text.trim(), coverPath: finalCoverPath,
authors: _authors, alternateTitles: _alternateTitles, publisher: _publisherController.text.trim(), authors: _authors, translators: _translators, alternateTitles: _alternateTitles, publisher: _publisherController.text.trim(),
genres: _genres, summary: _summaryController.text.trim(), rating: rating, status: _status, genres: _genres, summary: _summaryController.text.trim(), rating: rating, status: _status,
isbn: _isbnController.text.trim().isNotEmpty ? _isbnController.text.trim() : null, isbn: _isbnController.text.trim().isNotEmpty ? _isbnController.text.trim() : null,
publishDate: _publishDate, startDate: _startDate, finishDate: _finishDate, createdAt: now, updatedAt: now, publishDate: _publishDate, startDate: _startDate, finishDate: _finishDate, createdAt: now, updatedAt: now,
@@ -625,7 +635,7 @@ class _BookFormPageState extends State<BookFormPage> {
} else { } else {
final updatedBook = widget.book!.copyWith( final updatedBook = widget.book!.copyWith(
title: _titleController.text.trim(), coverPath: _coverPath, title: _titleController.text.trim(), coverPath: _coverPath,
authors: _authors, alternateTitles: _alternateTitles, publisher: _publisherController.text.trim(), authors: _authors, translators: _translators, alternateTitles: _alternateTitles, publisher: _publisherController.text.trim(),
genres: _genres, summary: _summaryController.text.trim(), rating: rating, status: _status, genres: _genres, summary: _summaryController.text.trim(), rating: rating, status: _status,
isbn: _isbnController.text.trim().isNotEmpty ? _isbnController.text.trim() : null, isbn: _isbnController.text.trim().isNotEmpty ? _isbnController.text.trim() : null,
publishDate: _publishDate, startDate: _startDate, finishDate: _finishDate, updatedAt: now, publishDate: _publishDate, startDate: _startDate, finishDate: _finishDate, updatedAt: now,

View File

@@ -140,24 +140,6 @@ class _BookReviewsPageState extends State<BookReviewsPage> {
), ),
), ),
const SizedBox(height: 24), const SizedBox(height: 24),
InkWell(
onTap: () => _navigateToAddReview(),
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
decoration: BoxDecoration(
color: colors.primary,
borderRadius: BorderRadius.circular(8),
),
child: Text(
'添加记录',
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
color: colors.onPrimary,
),
),
),
),
], ],
), ),
); );

View File

@@ -91,24 +91,6 @@ class _MoviePostersPageState extends State<MoviePostersPage> {
), ),
), ),
const SizedBox(height: 24), const SizedBox(height: 24),
InkWell(
onTap: _pickPoster,
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
decoration: BoxDecoration(
color: colors.primary,
borderRadius: BorderRadius.circular(8),
),
child: Text(
'添加记录',
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
color: colors.onPrimary,
),
),
),
),
], ],
), ),
); );

View File

@@ -140,24 +140,6 @@ class _MovieReviewsPageState extends State<MovieReviewsPage> {
), ),
), ),
const SizedBox(height: 24), const SizedBox(height: 24),
InkWell(
onTap: () => _navigateToAddReview(),
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
decoration: BoxDecoration(
color: colors.primary,
borderRadius: BorderRadius.circular(8),
),
child: Text(
'添加记录',
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.w500,
color: colors.onPrimary,
),
),
),
),
], ],
), ),
); );

View File

@@ -66,6 +66,7 @@ class _PersonListPageState extends State<PersonListPage> {
} }
for (final b in provider.books.where((b) => !b.isDeleted)) { for (final b in provider.books.where((b) => !b.isDeleted)) {
for (final a in b.authors) addRole(a, '作者', book: b); for (final a in b.authors) addRole(a, '作者', book: b);
for (final t in b.translators) addRole(t, '译者', book: b);
} }
var list = map.values.toList(); var list = map.values.toList();
@@ -119,7 +120,7 @@ class _PersonListPageState extends State<PersonListPage> {
style: TextStyle(fontSize: 15, color: colors.onSurface), style: TextStyle(fontSize: 15, color: colors.onSurface),
cursorColor: colors.primary, cursorColor: colors.primary,
decoration: InputDecoration( decoration: InputDecoration(
hintText: '搜索导演、编剧、演员、作者', hintText: '搜索导演、编剧、演员、作者、译者',
hintStyle: TextStyle(fontSize: 14, color: colors.onSurface.withValues(alpha: 0.3)), hintStyle: TextStyle(fontSize: 14, color: colors.onSurface.withValues(alpha: 0.3)),
isDense: true, isDense: true,
contentPadding: const EdgeInsets.symmetric(vertical: 12), contentPadding: const EdgeInsets.symmetric(vertical: 12),
@@ -156,7 +157,7 @@ class _PersonListPageState extends State<PersonListPage> {
padding: const EdgeInsets.fromLTRB(20, 10, 20, 4), padding: const EdgeInsets.fromLTRB(20, 10, 20, 4),
child: Row( child: Row(
children: [ children: [
for (final f in ['all', '导演', '编剧', '主演', '作者']) for (final f in ['all', '导演', '编剧', '主演', '作者', '译者'])
Padding( Padding(
padding: const EdgeInsets.only(right: 6), padding: const EdgeInsets.only(right: 6),
child: GestureDetector( child: GestureDetector(
@@ -208,6 +209,7 @@ class _PersonListPageState extends State<PersonListPage> {
'编剧': const Color(0xFF009688), '编剧': const Color(0xFF009688),
'主演': const Color(0xFFE91E63), '主演': const Color(0xFFE91E63),
'作者': const Color(0xFF7E57C2), '作者': const Color(0xFF7E57C2),
'译者': const Color(0xFFFF7043),
}; };
final totalWorks = person.movies.length + person.books.length; final totalWorks = person.movies.length + person.books.length;
return ListTile( return ListTile(
@@ -262,6 +264,7 @@ class _PersonDetailPage extends StatelessWidget {
'编剧': const Color(0xFF009688), '编剧': const Color(0xFF009688),
'主演': const Color(0xFFE91E63), '主演': const Color(0xFFE91E63),
'作者': const Color(0xFF7E57C2), '作者': const Color(0xFF7E57C2),
'译者': const Color(0xFFFF7043),
}; };
final movieItems = <_WorkItem>[]; final movieItems = <_WorkItem>[];
@@ -275,7 +278,10 @@ class _PersonDetailPage extends StatelessWidget {
movieItems.add(_WorkItem(title: m.title, roles: roles, path: m.posterPath, data: m)); movieItems.add(_WorkItem(title: m.title, roles: roles, path: m.posterPath, data: m));
} }
for (final b in person.books) { for (final b in person.books) {
bookItems.add(_WorkItem(title: b.title, roles: const ['作者'], path: b.coverPath, data: b)); final roles = <String>[];
if (b.authors.contains(person.name)) roles.add('作者');
if (b.translators.contains(person.name)) roles.add('译者');
bookItems.add(_WorkItem(title: b.title, roles: roles, path: b.coverPath, data: b));
} }
return Scaffold( return Scaffold(

View File

@@ -340,7 +340,7 @@ class _StrollPageState extends State<StrollPage> {
/// 有图片的卡片:全屏沉浸式 /// 有图片的卡片:全屏沉浸式
Widget _buildImmersiveCard(_StrollItem item, ColorScheme colors) { Widget _buildImmersiveCard(_StrollItem item, ColorScheme colors) {
return Container( return Container(
margin: const EdgeInsets.symmetric(vertical: 56, horizontal: 8), margin: const EdgeInsets.symmetric(vertical: 80, horizontal: 8),
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20), borderRadius: BorderRadius.circular(20),
boxShadow: [BoxShadow(color: Colors.black.withValues(alpha: 0.1), blurRadius: 20, offset: const Offset(0, 8))], boxShadow: [BoxShadow(color: Colors.black.withValues(alpha: 0.1), blurRadius: 20, offset: const Offset(0, 8))],
@@ -382,7 +382,7 @@ class _StrollPageState extends State<StrollPage> {
/// 无图片的卡片:内容从顶部开始 /// 无图片的卡片:内容从顶部开始
Widget _buildContentCard(_StrollItem item, ColorScheme colors) { Widget _buildContentCard(_StrollItem item, ColorScheme colors) {
return Container( return Container(
margin: const EdgeInsets.symmetric(vertical: 56, horizontal: 8), margin: const EdgeInsets.symmetric(vertical: 80, horizontal: 8),
decoration: BoxDecoration( decoration: BoxDecoration(
color: colors.surface, color: colors.surface,
borderRadius: BorderRadius.circular(20), borderRadius: BorderRadius.circular(20),

View File

@@ -72,7 +72,7 @@ class DatabaseHelper {
return await openDatabase( return await openDatabase(
path, path,
version: 28, version: 29,
onCreate: _createDB, onCreate: _createDB,
onUpgrade: _onUpgrade, onUpgrade: _onUpgrade,
); );
@@ -255,6 +255,13 @@ class DatabaseHelper {
// 移除 Note Plus 功能,删除 note_plus 表 // 移除 Note Plus 功能,删除 note_plus 表
await db.execute('DROP TABLE IF EXISTS note_plus'); await db.execute('DROP TABLE IF EXISTS note_plus');
} }
if (oldVersion < 29) {
// 为书籍表添加译者字段
final bookCols = await db.rawQuery('PRAGMA table_info(books)');
if (!bookCols.any((col) => col['name'] == 'translators')) {
await db.execute('ALTER TABLE books ADD COLUMN translators TEXT');
}
}
} }
/// 升级books表到V27添加阅读始末日期字段 /// 升级books表到V27添加阅读始末日期字段
@@ -665,6 +672,7 @@ class DatabaseHelper {
title TEXT NOT NULL, title TEXT NOT NULL,
cover_path TEXT, cover_path TEXT,
authors TEXT, authors TEXT,
translators TEXT,
alternate_titles TEXT, alternate_titles TEXT,
publisher TEXT, publisher TEXT,
genres TEXT, genres TEXT,

View File

@@ -1,9 +1,11 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'dart:io' show Platform; import 'dart:io' show Platform;
import 'dart:math'; import 'package:crypto/crypto.dart';
import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:package_info_plus/package_info_plus.dart';
import 'user_prefs.dart'; import 'user_prefs.dart';
import 'server_config.dart'; import 'server_config.dart';
@@ -59,16 +61,40 @@ class UsageStatsService with WidgetsBindingObserver {
/// 确保设备有匿名ID /// 确保设备有匿名ID
Future<void> _ensureDeviceId() async { Future<void> _ensureDeviceId() async {
if (_prefs.deviceId.isEmpty) { if (_prefs.deviceId.isEmpty) {
final id = _generateDeviceId(); final id = await _generateDeviceId();
await _prefs.setDeviceId(id); await _prefs.setDeviceId(id);
} }
} }
/// 生成匿名设备标识 /// 基于设备硬件信息生成匿名设备标识SHA-256 哈希)
String _generateDeviceId() { Future<String> _generateDeviceId() async {
final random = Random.secure(); final deviceInfo = DeviceInfoPlugin();
final bytes = List<int>.generate(16, (_) => random.nextInt(256)); String rawId;
final hex = bytes.map((b) => b.toRadixString(16).padLeft(2, '0')).join();
if (Platform.isAndroid) {
final info = await deviceInfo.androidInfo;
rawId = info.id; // Settings.Secure.ANDROID_ID
} else if (Platform.isIOS) {
final info = await deviceInfo.iosInfo;
rawId = info.identifierForVendor ?? '';
} else if (Platform.isWindows) {
final info = await deviceInfo.windowsInfo;
rawId = '${info.computerName}-${info.numberOfCores}';
} else if (Platform.isMacOS) {
final info = await deviceInfo.macOsInfo;
rawId = '${info.computerName}-${info.systemGUID ?? ''}';
} else if (Platform.isLinux) {
final info = await deviceInfo.linuxInfo;
rawId = '${info.name}-${info.id}';
} else {
rawId = DateTime.now().millisecondsSinceEpoch.toString();
}
final bytes = utf8.encode(rawId);
final hash = sha256.convert(bytes);
final hex = hash.toString();
// 格式化为 UUID 样式
return '${hex.substring(0, 8)}-' return '${hex.substring(0, 8)}-'
'${hex.substring(8, 12)}-' '${hex.substring(8, 12)}-'
'${hex.substring(12, 16)}-' '${hex.substring(12, 16)}-'
@@ -83,6 +109,12 @@ class UsageStatsService with WidgetsBindingObserver {
if (deviceId.isEmpty) return; if (deviceId.isEmpty) return;
try { try {
String appVersion = '';
try {
final pkgInfo = await PackageInfo.fromPlatform();
appVersion = '${pkgInfo.version}+${pkgInfo.buildNumber}';
} catch (_) {}
await http await http
.post( .post(
Uri.parse('$serverUrl/api/heartbeat'), Uri.parse('$serverUrl/api/heartbeat'),
@@ -93,6 +125,7 @@ class UsageStatsService with WidgetsBindingObserver {
Platform.operatingSystem, // android/ios/windows/macos/linux Platform.operatingSystem, // android/ios/windows/macos/linux
'device_name': 'device_name':
'${Platform.operatingSystem} ${Platform.operatingSystemVersion}', '${Platform.operatingSystem} ${Platform.operatingSystemVersion}',
'app_version': appVersion,
}), }),
) )
.timeout(const Duration(seconds: 5)); .timeout(const Duration(seconds: 5));

View File

@@ -210,6 +210,8 @@ class _TagSidePanelState extends State<TagSidePanel> {
Expanded( Expanded(
child: SingleChildScrollView( child: SingleChildScrollView(
padding: const EdgeInsets.fromLTRB(16, 8, 16, 24), padding: const EdgeInsets.fromLTRB(16, 8, 16, 24),
child: SizedBox(
width: double.infinity,
child: Wrap( child: Wrap(
spacing: 8, spacing: 8,
runSpacing: 8, runSpacing: 8,
@@ -243,6 +245,7 @@ class _TagSidePanelState extends State<TagSidePanel> {
), ),
), ),
), ),
),
], ],
), ),
), ),

View File

@@ -5,6 +5,7 @@
import FlutterMacOS import FlutterMacOS
import Foundation import Foundation
import device_info_plus
import dynamic_color import dynamic_color
import file_picker import file_picker
import file_selector_macos import file_selector_macos
@@ -16,6 +17,7 @@ import sqflite_darwin
import url_launcher_macos import url_launcher_macos
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
DynamicColorPlugin.register(with: registry.registrar(forPlugin: "DynamicColorPlugin")) DynamicColorPlugin.register(with: registry.registrar(forPlugin: "DynamicColorPlugin"))
FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin")) FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin"))
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))

View File

@@ -90,13 +90,29 @@ packages:
source: hosted source: hosted
version: "0.3.5+2" version: "0.3.5+2"
crypto: crypto:
dependency: transitive dependency: "direct main"
description: description:
name: crypto name: crypto
sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.7" version: "3.0.7"
device_info_plus:
dependency: "direct main"
description:
name: device_info_plus
sha256: "98f28b42168cc509abc92f88518882fd58061ea372d7999aecc424345c7bff6a"
url: "https://pub.dev"
source: hosted
version: "11.5.0"
device_info_plus_platform_interface:
dependency: transitive
description:
name: device_info_plus_platform_interface
sha256: e1ea89119e34903dca74b883d0dd78eb762814f97fb6c76f35e9ff74d261a18f
url: "https://pub.dev"
source: hosted
version: "7.0.3"
dynamic_color: dynamic_color:
dependency: "direct main" dependency: "direct main"
description: description:
@@ -1042,6 +1058,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "5.15.0" version: "5.15.0"
win32_registry:
dependency: transitive
description:
name: win32_registry
sha256: "6f1b564492d0147b330dd794fee8f512cec4977957f310f9951b5f9d83618dae"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
xdg_directories: xdg_directories:
dependency: transitive dependency: transitive
description: description:

View File

@@ -34,6 +34,8 @@ dependencies:
uuid: ^4.5.0 uuid: ^4.5.0
expandable: ^5.0.1 expandable: ^5.0.1
sqflite_common_ffi: ^2.3.0 sqflite_common_ffi: ^2.3.0
device_info_plus: ^11.2.0
crypto: ^3.0.6
dev_dependencies: dev_dependencies:
flutter_test: flutter_test: