From 3f3e5202491c37d3fccaa9ec59add1b1413c4628 Mon Sep 17 00:00:00 2001 From: hejl Date: Sun, 11 May 2025 10:00:32 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BC=80=E5=A7=8B=E6=AD=A5=E5=85=A5=E6=AD=A3?= =?UTF-8?q?=E8=BD=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/app/menus/menu_actions.dart | 8 +- .../lib/app/models/editor_tab.dart | 16 -- .../lib/app/providers/editor_provider.dart | 36 ++-- .../lib/app/widgets/editor_pane.dart | 90 ++++----- .../lib/app/widgets/file_explorer.dart | 114 +++++++---- .../lib/app/widgets/template_parser.dart | 38 ---- .../lib/app/widgets/text_editor.dart | 181 ------------------ win_text_editor/lib/app/widgets/text_tab.dart | 96 ++++++++++ win_text_editor/pubspec.lock | 106 +++++----- 9 files changed, 283 insertions(+), 402 deletions(-) delete mode 100644 win_text_editor/lib/app/models/editor_tab.dart delete mode 100644 win_text_editor/lib/app/widgets/template_parser.dart delete mode 100644 win_text_editor/lib/app/widgets/text_editor.dart create mode 100644 win_text_editor/lib/app/widgets/text_tab.dart diff --git a/win_text_editor/lib/app/menus/menu_actions.dart b/win_text_editor/lib/app/menus/menu_actions.dart index acc3ecb..de857f8 100644 --- a/win_text_editor/lib/app/menus/menu_actions.dart +++ b/win_text_editor/lib/app/menus/menu_actions.dart @@ -3,12 +3,9 @@ import 'package:file_picker/file_picker.dart'; import 'package:provider/provider.dart'; import 'package:win_text_editor/app/menus/menu_constants.dart'; import 'package:win_text_editor/app/providers/file_provider.dart'; +import 'package:win_text_editor/app/providers/editor_provider.dart'; import 'dart:io'; -import '../models/editor_tab.dart'; -import '../providers/editor_provider.dart'; -import '../widgets/template_parser.dart'; // 确保导入了TemplateParser - class MenuActions { static Future handleMenuAction(String value, BuildContext context) async { switch (value) { @@ -35,8 +32,7 @@ class MenuActions { } static void _openTemplateParser(BuildContext context) { - final editorProvider = Provider.of(context, listen: false); - editorProvider.addTemplateParserTab(); + Provider.of(context, listen: false).addTab(); } static void _exitApplication() { diff --git a/win_text_editor/lib/app/models/editor_tab.dart b/win_text_editor/lib/app/models/editor_tab.dart deleted file mode 100644 index df1e46e..0000000 --- a/win_text_editor/lib/app/models/editor_tab.dart +++ /dev/null @@ -1,16 +0,0 @@ -// models/editor_tab.dart -enum EditorTabType { - blank, // 空白 - template, // 模板解析 - fileEditor, // 文件编辑器 - // 可以添加更多类型 -} - -class EditorTab { - final String id; - final String title; - final EditorTabType type; - final dynamic content; // 可存储不同类型的内容 - - EditorTab({required this.id, required this.title, required this.type, this.content}); -} diff --git a/win_text_editor/lib/app/providers/editor_provider.dart b/win_text_editor/lib/app/providers/editor_provider.dart index 4206fd9..7d0085d 100644 --- a/win_text_editor/lib/app/providers/editor_provider.dart +++ b/win_text_editor/lib/app/providers/editor_provider.dart @@ -1,17 +1,22 @@ import 'package:flutter/material.dart'; -import 'package:win_text_editor/app/models/editor_tab.dart'; -// providers/editor_provider.dart class EditorProvider with ChangeNotifier { - List _tabs = []; + final List _tabs = []; String? _activeTabId; List get tabs => _tabs; String? get activeTabId => _activeTabId; - void addTab(EditorTab tab) { - _tabs.add(tab); - _activeTabId = tab.id; + void addTab() { + final tabId = DateTime.now().millisecondsSinceEpoch.toString(); + _tabs.add( + EditorTab( + id: tabId, + title: '文档 ${_tabs.length + 1}', + content: '', // 初始空内容 + ), + ); + _activeTabId = tabId; notifyListeners(); } @@ -28,13 +33,16 @@ class EditorProvider with ChangeNotifier { notifyListeners(); } - // 添加模板解析标签 - void addTemplateParserTab() { - final tab = EditorTab( - id: 'template-${DateTime.now().millisecondsSinceEpoch}', - title: '模板解析 ${_tabs.where((t) => t.type == EditorTabType.template).length + 1}', - type: EditorTabType.template, - ); - addTab(tab); + void updateContent(String tabId, String content) { + final tab = _tabs.firstWhere((t) => t.id == tabId); + tab.content = content; } } + +class EditorTab { + final String id; + final String title; + String content; + + EditorTab({required this.id, required this.title, required this.content}); +} diff --git a/win_text_editor/lib/app/widgets/editor_pane.dart b/win_text_editor/lib/app/widgets/editor_pane.dart index 8d1a215..af99b9b 100644 --- a/win_text_editor/lib/app/widgets/editor_pane.dart +++ b/win_text_editor/lib/app/widgets/editor_pane.dart @@ -1,80 +1,54 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; - -import '../models/editor_tab.dart'; -import '../providers/editor_provider.dart'; -// import 'template_parser.dart'; +import 'package:win_text_editor/app/providers/editor_provider.dart'; +import 'text_tab.dart'; class EditorPane extends StatelessWidget { const EditorPane({super.key}); @override Widget build(BuildContext context) { - final editorProvider = Provider.of(context); + final provider = Provider.of(context); - return Container( - color: Colors.white, - child: Column( - children: [ - // 标签栏 - _buildTabBar(context), - // 内容区域 - Expanded( - child: - editorProvider.tabs.isEmpty - ? const Center(child: Text('空白区域', style: TextStyle(color: Colors.grey))) - : _buildCurrentTabContent(context), + return Column( + children: [ + // 标签栏 + SizedBox( + height: 40, + child: ListView.builder( + scrollDirection: Axis.horizontal, + itemCount: provider.tabs.length, + itemBuilder: (ctx, index) { + final tab = provider.tabs[index]; + return _TabItem( + title: tab.title, + isActive: tab.id == provider.activeTabId, + onClose: () => provider.closeTab(tab.id), + onTap: () => provider.setActiveTab(tab.id), + ); + }, ), - ], - ), - ); - } - - Widget _buildTabBar(BuildContext context) { - final editorProvider = Provider.of(context); - - return SizedBox( - height: 40, - child: ListView.builder( - scrollDirection: Axis.horizontal, - itemCount: editorProvider.tabs.length, - itemBuilder: (ctx, index) { - final tab = editorProvider.tabs[index]; - return _TabItem( - tab: tab, - isActive: tab.id == editorProvider.activeTabId, - onClose: () => editorProvider.closeTab(tab.id), - onTap: () => editorProvider.setActiveTab(tab.id), - ); - }, - ), - ); - } - - Widget _buildCurrentTabContent(BuildContext context) { - final editorProvider = Provider.of(context); - final activeTab = editorProvider.tabs.firstWhere( - (tab) => tab.id == editorProvider.activeTabId, - orElse: () => editorProvider.tabs.first, + ), + // 内容区 + Expanded( + child: + provider.activeTabId != null + ? TextTab(tabId: provider.activeTabId!) + : const Center(child: Text('无活动标签页')), + ), + ], ); - - switch (activeTab.type) { - case EditorTabType.template: - return Container(); //TemplateParser(); // 你的模板解析组件 - default: - return Container(); // 空白或其他默认视图 - } } } class _TabItem extends StatelessWidget { - final EditorTab tab; + final String title; final bool isActive; final VoidCallback onClose; final VoidCallback onTap; const _TabItem({ - required this.tab, + required this.title, required this.isActive, required this.onClose, required this.onTap, @@ -94,7 +68,7 @@ class _TabItem extends StatelessWidget { ), child: Row( children: [ - Text(tab.title), + Text(title), const SizedBox(width: 8), IconButton(icon: const Icon(Icons.close, size: 16), onPressed: onClose), ], diff --git a/win_text_editor/lib/app/widgets/file_explorer.dart b/win_text_editor/lib/app/widgets/file_explorer.dart index 7691e96..15598bc 100644 --- a/win_text_editor/lib/app/widgets/file_explorer.dart +++ b/win_text_editor/lib/app/widgets/file_explorer.dart @@ -6,6 +6,8 @@ import '../models/file_node.dart'; import '../providers/file_provider.dart'; import '../providers/editor_provider.dart'; +import 'dart:math'; + class FileExplorer extends StatefulWidget { const FileExplorer({super.key}); @@ -14,11 +16,13 @@ class FileExplorer extends StatefulWidget { } class _FileExplorerState extends State { - final ScrollController _scrollController = ScrollController(); // 添加这行 + final ScrollController _verticalScrollController = ScrollController(); + final ScrollController _horizontalScrollController = ScrollController(); @override void dispose() { - _scrollController.dispose(); // 记得释放资源 + _verticalScrollController.dispose(); + _horizontalScrollController.dispose(); super.dispose(); } @@ -36,6 +40,28 @@ class _FileExplorerState extends State { } } + Widget _buildEmptyPrompt(BuildContext context) { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Text('No directory selected'), + TextButton(onPressed: () => _promptForDirectory(context), child: const Text('Open Folder')), + ], + ); + } + + void _handleNodeTap(BuildContext context, FileNode node) async { + final fileProvider = Provider.of(context, listen: false); + if (node.isDirectory) { + await fileProvider.loadDirectoryContents(node); + } else { + // 如果是文件,可以在这里添加打开文件的逻辑 + // 例如: + // final editorProvider = Provider.of(context, listen: false); + // editorProvider.openFile(node.path); + } + } + @override Widget build(BuildContext context) { final fileProvider = Provider.of(context); @@ -45,48 +71,64 @@ class _FileExplorerState extends State { child: Column( children: [ Expanded( - child: Scrollbar( - controller: _scrollController, // 添加控制器绑定 - thumbVisibility: true, // 始终显示滚动条 - interactive: true, // 启用滚动条拖动交互 - child: - fileProvider.isLoading - ? const Center(child: CircularProgressIndicator()) - : fileProvider.fileNodes.isEmpty - ? Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - const Text('No directory selected'), - TextButton( - onPressed: () => _promptForDirectory(context), - child: const Text('Open Folder'), + child: + fileProvider.isLoading + ? const Center(child: CircularProgressIndicator()) + : fileProvider.fileNodes.isEmpty + ? Center(child: _buildEmptyPrompt(context)) + : Scrollbar( + // 外层:垂直滚动条 + controller: _verticalScrollController, + thumbVisibility: true, + child: SingleChildScrollView( + // 中层:水平滚动 + scrollDirection: Axis.horizontal, + controller: _horizontalScrollController, + child: Scrollbar( + // 内层:水平滚动条(横向) + controller: _horizontalScrollController, + thumbVisibility: true, + scrollbarOrientation: ScrollbarOrientation.bottom, // 横向滚动条在底部 + child: SizedBox( + width: _calculateTotalWidth(context, fileProvider), // 动态计算总宽度 + child: ListView.builder( + // 内层:垂直列表 + controller: _verticalScrollController, + itemCount: _countVisibleNodes(fileProvider.fileNodes), + itemBuilder: (context, index) { + final node = _getVisibleNode(fileProvider.fileNodes, index); + return _FileNodeWidget( + key: ValueKey(node.path), + node: node, + onTap: () => _handleNodeTap(context, node), + ); + }, ), - ], + ), ), - ) - : ListView.builder( - controller: _scrollController, // 确保ListView使用相同的控制器 - itemCount: _countVisibleNodes(fileProvider.fileNodes), - itemBuilder: (context, index) { - final node = _getVisibleNode(fileProvider.fileNodes, index); - return _FileNodeWidget( - key: ValueKey(node.path), - node: node, - onTap: () async { - if (node.isDirectory) { - await fileProvider.loadDirectoryContents(node); - } - }, - ); - }, ), - ), + ), ), ], ), ); } + + // 动态计算总宽度(示例:根据层级深度调整) + double _calculateTotalWidth(BuildContext context, FileProvider fileProvider) { + final maxDepth = _getMaxDepth(fileProvider.fileNodes); + return maxDepth * 200 + MediaQuery.of(context).size.width * 0.5; + } + + int _getMaxDepth(List nodes) { + int maxDepth = 0; + for (final node in nodes) { + if (node.isDirectory && node.isExpanded) { + maxDepth = max(maxDepth, _getMaxDepth(node.children) + 1); + } + } + return maxDepth; + } } // 辅助方法:计算所有可见节点数量 diff --git a/win_text_editor/lib/app/widgets/template_parser.dart b/win_text_editor/lib/app/widgets/template_parser.dart deleted file mode 100644 index a733501..0000000 --- a/win_text_editor/lib/app/widgets/template_parser.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:flutter/material.dart'; -// import 'text_editor.dart'; - -class TemplateParser extends StatefulWidget { - final String? initialContent; - - const TemplateParser({Key? key, this.initialContent}) : super(key: key); - - @override - State createState() => _TemplateParserState(); -} - -class _TemplateParserState extends State { - late String _currentContent; - - @override - void initState() { - super.initState(); - _currentContent = widget.initialContent ?? '这里是模板解析器的初始内容'; - } - - @override - Widget build(BuildContext context) { - return Card( - margin: EdgeInsets.zero, - color: Colors.grey[100], - // child: TextEditor( - // editorTitle: '模板解析器', - // initialContent: _currentContent, - // onContentChanged: (newContent) { - // setState(() { - // _currentContent = newContent; - // }); - // }, - // ), - ); - } -} diff --git a/win_text_editor/lib/app/widgets/text_editor.dart b/win_text_editor/lib/app/widgets/text_editor.dart deleted file mode 100644 index c358a5e..0000000 --- a/win_text_editor/lib/app/widgets/text_editor.dart +++ /dev/null @@ -1,181 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; - -class TextEditor extends StatefulWidget { - final String? initialContent; - final String editorTitle; - final bool showToolbar; - final ValueChanged? onContentChanged; - - const TextEditor({ - Key? key, - this.initialContent, - this.editorTitle = '源文本', - this.showToolbar = true, - this.onContentChanged, - }) : super(key: key); - - @override - State createState() => _TextEditorState(); -} - -class _TextEditorState extends State { - late final TextEditingController _textController; - late String _currentFileName; - final ScrollController _scrollController = ScrollController(); - - @override - void initState() { - super.initState(); - _textController = TextEditingController(text: widget.initialContent); - _currentFileName = "未命名文件"; - _textController.addListener(_handleTextChanged); - } - - void _handleTextChanged() { - widget.onContentChanged?.call(_textController.text); - } - - @override - void didUpdateWidget(TextEditor oldWidget) { - super.didUpdateWidget(oldWidget); - if (widget.initialContent != oldWidget.initialContent && - widget.initialContent != _textController.text) { - _textController.text = widget.initialContent ?? ''; - } - } - - @override - void dispose() { - _textController.removeListener(_handleTextChanged); - _textController.dispose(); - _scrollController.dispose(); - super.dispose(); - } - - Future _openFile() async { - const String mockFileContent = """这是从文件加载的示例文本: -第1行内容 -第2行内容 -第3行内容"""; - - setState(() { - _textController.text = mockFileContent; - _currentFileName = "示例文件.txt"; - }); - } - - Future _copyToClipboard() async { - if (_textController.text.isNotEmpty) { - await Clipboard.setData(ClipboardData(text: _textController.text)); - if (mounted) { - ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('已复制全部文本到剪贴板'))); - } - } - } - - Future _saveFile() async { - if (_textController.text.isEmpty) return; - - if (mounted) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text('文件 "$_currentFileName" 保存成功'), - duration: const Duration(seconds: 2), - ), - ); - } - } - - @override - Widget build(BuildContext context) { - return Column( - children: [ - if (widget.showToolbar) ...[ - Container( - padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), - decoration: BoxDecoration( - color: Colors.blue[50], - border: Border(bottom: BorderSide(color: Colors.grey[300]!)), - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - widget.editorTitle, - style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold), - ), - Row( - children: [ - IconButton( - icon: const Icon(Icons.folder_open, size: 20), - tooltip: '打开文件', - onPressed: _openFile, - ), - IconButton( - icon: const Icon(Icons.content_copy, size: 20), - tooltip: '复制全部', - onPressed: _copyToClipboard, - ), - IconButton( - icon: const Icon(Icons.save, size: 20), - tooltip: '保存文件', - onPressed: _saveFile, - ), - ], - ), - ], - ), - ), - ], - Expanded(child: _buildEditorField()), - ], - ); - } - - Widget _buildEditorField() { - return ScrollConfiguration( - behavior: _NoScrollBehavior(), - child: SingleChildScrollView( - controller: _scrollController, - physics: const ClampingScrollPhysics(), - child: ConstrainedBox( - constraints: BoxConstraints(minHeight: MediaQuery.of(context).size.height), - child: Padding( - padding: const EdgeInsets.all(8.0), - child: TextField( - controller: _textController, - maxLines: null, - scrollPhysics: const NeverScrollableScrollPhysics(), - decoration: InputDecoration( - hintText: '在此输入文本...', - border: InputBorder.none, - filled: true, - fillColor: Colors.white, - contentPadding: const EdgeInsets.all(12.0), - ), - style: const TextStyle(fontSize: 14), - ), - ), - ), - ), - ); - } -} - -class _NoScrollBehavior extends ScrollBehavior { - @override - Widget buildScrollbar(BuildContext context, Widget child, ScrollableDetails details) { - return child; - } - - @override - Widget buildOverscrollIndicator(BuildContext context, Widget child, ScrollableDetails details) { - return child; - } - - @override - ScrollPhysics getScrollPhysics(BuildContext context) { - return const ClampingScrollPhysics(); - } -} diff --git a/win_text_editor/lib/app/widgets/text_tab.dart b/win_text_editor/lib/app/widgets/text_tab.dart new file mode 100644 index 0000000..775be47 --- /dev/null +++ b/win_text_editor/lib/app/widgets/text_tab.dart @@ -0,0 +1,96 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:flutter/services.dart'; // 复制功能需要 +import 'package:win_text_editor/app/providers/editor_provider.dart'; + +class TextTab extends StatelessWidget { + final String tabId; + + const TextTab({super.key, required this.tabId}); + + @override + Widget build(BuildContext context) { + final provider = Provider.of(context); + final tab = provider.tabs.firstWhere((t) => t.id == tabId); + + return Column( + children: [ + // 新增工具条 + Container( + height: 40, + padding: const EdgeInsets.symmetric(horizontal: 16), + decoration: BoxDecoration( + color: Colors.grey[100], + border: Border(bottom: BorderSide(color: Colors.grey[300]!)), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const Text('源文本', style: TextStyle(fontWeight: FontWeight.bold)), + Row( + children: [ + IconButton( + icon: const Icon(Icons.folder_open, size: 20), + tooltip: '打开文件', + onPressed: () => _openFile(context, tabId), + ), + IconButton( + icon: const Icon(Icons.content_copy, size: 20), + tooltip: '复制内容', + onPressed: () => _copyToClipboard(context, tab.content), + ), + IconButton( + icon: const Icon(Icons.save, size: 20), + tooltip: '保存文件', + onPressed: () => _saveFile(context, tab.content), + ), + ], + ), + ], + ), + ), + // 文本编辑区 + Expanded( + child: TextField( + maxLines: null, + controller: TextEditingController(text: tab.content), + onChanged: (text) => provider.updateContent(tabId, text), + decoration: const InputDecoration( + border: InputBorder.none, + hintText: '开始输入内容...', + contentPadding: EdgeInsets.all(16), + ), + ), + ), + ], + ); + } + + // 打开文件模拟功能 + Future _openFile(BuildContext context, String tabId) async { + final provider = Provider.of(context, listen: false); + // 这里是模拟代码,实际应该使用文件选择器 + const mockContent = "从文件加载的示例文本..."; + provider.updateContent(tabId, mockContent); + + ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('已加载文件内容'))); + } + + // 复制到剪贴板 + Future _copyToClipboard(BuildContext context, String content) async { + await Clipboard.setData(ClipboardData(text: content)); + if (context.mounted) { + ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('已复制到剪贴板'))); + } + } + + // 保存文件模拟功能 + Future _saveFile(BuildContext context, String content) async { + // 这里是模拟代码,实际应该使用文件保存对话框 + if (context.mounted) { + ScaffoldMessenger.of( + context, + ).showSnackBar(SnackBar(content: Text('已保存 ${content.length} 个字符'))); + } + } +} diff --git a/win_text_editor/pubspec.lock b/win_text_editor/pubspec.lock index 25e72e5..b887ca7 100644 --- a/win_text_editor/pubspec.lock +++ b/win_text_editor/pubspec.lock @@ -6,7 +6,7 @@ packages: description: name: async sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.12.0" bitsdojo_window: @@ -14,7 +14,7 @@ packages: description: name: bitsdojo_window sha256: "88ef7765dafe52d97d7a3684960fb5d003e3151e662c18645c1641c22b873195" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.1.6" bitsdojo_window_linux: @@ -22,7 +22,7 @@ packages: description: name: bitsdojo_window_linux sha256: "9519c0614f98be733e0b1b7cb15b827007886f6fe36a4fb62cf3d35b9dd578ab" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.1.4" bitsdojo_window_macos: @@ -30,7 +30,7 @@ packages: description: name: bitsdojo_window_macos sha256: f7c5be82e74568c68c5b8449e2c5d8fd12ec195ecd70745a7b9c0f802bb0268f - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.1.4" bitsdojo_window_platform_interface: @@ -38,7 +38,7 @@ packages: description: name: bitsdojo_window_platform_interface sha256: "65daa015a0c6dba749bdd35a0f092e7a8ba8b0766aa0480eb3ef808086f6e27c" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.1.2" bitsdojo_window_windows: @@ -46,7 +46,7 @@ packages: description: name: bitsdojo_window_windows sha256: fa982cf61ede53f483e50b257344a1c250af231a3cdc93a7064dd6dc0d720b68 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.1.6" boolean_selector: @@ -54,7 +54,7 @@ packages: description: name: boolean_selector sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.2" characters: @@ -62,7 +62,7 @@ packages: description: name: characters sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.4.0" clock: @@ -70,7 +70,7 @@ packages: description: name: clock sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.1.2" collection: @@ -78,7 +78,7 @@ packages: description: name: collection sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.19.1" cross_file: @@ -86,7 +86,7 @@ packages: description: name: cross_file sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.3.4+2" expandable: @@ -94,7 +94,7 @@ packages: description: name: expandable sha256: "9604d612d4d1146dafa96c6d8eec9c2ff0994658d6d09fed720ab788c7f5afc2" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "5.0.1" fake_async: @@ -102,7 +102,7 @@ packages: description: name: fake_async sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.3.2" ffi: @@ -110,17 +110,17 @@ packages: description: name: ffi sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.4" file_picker: dependency: "direct main" description: name: file_picker - sha256: "978be1f602e0695daef8e345a3c597abf72b0c0ca6102fa2665eb549f5406a17" - url: "https://pub.dev" + sha256: a222f231db4f822fc49e3b753674bda630e981873c84bf8604bceeb77fce0b24 + url: "https://pub.flutter-io.cn" source: hosted - version: "10.1.5" + version: "10.1.7" flutter: dependency: "direct main" description: flutter @@ -131,7 +131,7 @@ packages: description: name: flutter_lints sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.0.3" flutter_plugin_android_lifecycle: @@ -139,7 +139,7 @@ packages: description: name: flutter_plugin_android_lifecycle sha256: f948e346c12f8d5480d2825e03de228d0eb8c3a737e4cdaa122267b89c022b5e - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.0.28" flutter_syntax_view: @@ -147,7 +147,7 @@ packages: description: name: flutter_syntax_view sha256: c5017bbedfdcf538daba765e16541fcb26434071655ca00cea7cbc205a70246a - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "4.1.7" flutter_test: @@ -165,7 +165,7 @@ packages: description: name: leak_tracker sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "10.0.8" leak_tracker_flutter_testing: @@ -173,7 +173,7 @@ packages: description: name: leak_tracker_flutter_testing sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "3.0.9" leak_tracker_testing: @@ -181,7 +181,7 @@ packages: description: name: leak_tracker_testing sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "3.0.1" lints: @@ -189,7 +189,7 @@ packages: description: name: lints sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.1" matcher: @@ -197,7 +197,7 @@ packages: description: name: matcher sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.12.17" material_color_utilities: @@ -205,7 +205,7 @@ packages: description: name: material_color_utilities sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.11.1" meta: @@ -213,7 +213,7 @@ packages: description: name: meta sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.16.0" nested: @@ -221,7 +221,7 @@ packages: description: name: nested sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.0.0" path: @@ -229,7 +229,7 @@ packages: description: name: path sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.9.1" path_provider: @@ -237,7 +237,7 @@ packages: description: name: path_provider sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.5" path_provider_android: @@ -245,7 +245,7 @@ packages: description: name: path_provider_android sha256: d0d310befe2c8ab9e7f393288ccbb11b60c019c6b5afc21973eeee4dda2b35e9 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.2.17" path_provider_foundation: @@ -253,7 +253,7 @@ packages: description: name: path_provider_foundation sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.4.1" path_provider_linux: @@ -261,7 +261,7 @@ packages: description: name: path_provider_linux sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.2.1" path_provider_platform_interface: @@ -269,7 +269,7 @@ packages: description: name: path_provider_platform_interface sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.2" path_provider_windows: @@ -277,7 +277,7 @@ packages: description: name: path_provider_windows sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.3.0" platform: @@ -285,7 +285,7 @@ packages: description: name: platform sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "3.1.6" plugin_platform_interface: @@ -293,7 +293,7 @@ packages: description: name: plugin_platform_interface sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.8" provider: @@ -301,7 +301,7 @@ packages: description: name: provider sha256: "4abbd070a04e9ddc287673bf5a030c7ca8b685ff70218720abab8b092f53dd84" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "6.1.5" screen_retriever: @@ -309,7 +309,7 @@ packages: description: name: screen_retriever sha256: "6ee02c8a1158e6dae7ca430da79436e3b1c9563c8cf02f524af997c201ac2b90" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.1.9" sky_engine: @@ -322,7 +322,7 @@ packages: description: name: source_span sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.10.1" stack_trace: @@ -330,7 +330,7 @@ packages: description: name: stack_trace sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.12.1" stream_channel: @@ -338,7 +338,7 @@ packages: description: name: stream_channel sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.4" string_scanner: @@ -346,7 +346,7 @@ packages: description: name: string_scanner sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.4.1" term_glyph: @@ -354,7 +354,7 @@ packages: description: name: term_glyph sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.2.2" test_api: @@ -362,7 +362,7 @@ packages: description: name: test_api sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.7.4" vector_math: @@ -370,7 +370,7 @@ packages: description: name: vector_math sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.4" vm_service: @@ -378,7 +378,7 @@ packages: description: name: vm_service sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "14.3.1" web: @@ -386,23 +386,23 @@ packages: description: name: web sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.1.1" win32: dependency: transitive description: name: win32 - sha256: dc6ecaa00a7c708e5b4d10ee7bec8c270e9276dfcab1783f57e9962d7884305f - url: "https://pub.dev" + sha256: "329edf97fdd893e0f1e3b9e88d6a0e627128cc17cc316a8d67fda8f1451178ba" + url: "https://pub.flutter-io.cn" source: hosted - version: "5.12.0" + version: "5.13.0" window_manager: dependency: "direct main" description: name: window_manager sha256: "8699323b30da4cdbe2aa2e7c9de567a6abd8a97d9a5c850a3c86dcd0b34bbfbf" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "0.3.9" xdg_directories: @@ -410,7 +410,7 @@ packages: description: name: xdg_directories sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" - url: "https://pub.dev" + url: "https://pub.flutter-io.cn" source: hosted version: "1.1.0" sdks: