Browse Source

开始步入正轨

master
hejl 2 months ago
parent
commit
3f3e520249
  1. 8
      win_text_editor/lib/app/menus/menu_actions.dart
  2. 16
      win_text_editor/lib/app/models/editor_tab.dart
  3. 36
      win_text_editor/lib/app/providers/editor_provider.dart
  4. 90
      win_text_editor/lib/app/widgets/editor_pane.dart
  5. 114
      win_text_editor/lib/app/widgets/file_explorer.dart
  6. 38
      win_text_editor/lib/app/widgets/template_parser.dart
  7. 181
      win_text_editor/lib/app/widgets/text_editor.dart
  8. 96
      win_text_editor/lib/app/widgets/text_tab.dart
  9. 106
      win_text_editor/pubspec.lock

8
win_text_editor/lib/app/menus/menu_actions.dart

@ -3,12 +3,9 @@ import 'package:file_picker/file_picker.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<void> handleMenuAction(String value, BuildContext context) async {
switch (value) {
@ -35,8 +32,7 @@ class MenuActions { @@ -35,8 +32,7 @@ class MenuActions {
}
static void _openTemplateParser(BuildContext context) {
final editorProvider = Provider.of<EditorProvider>(context, listen: false);
editorProvider.addTemplateParserTab();
Provider.of<EditorProvider>(context, listen: false).addTab();
}
static void _exitApplication() {

16
win_text_editor/lib/app/models/editor_tab.dart

@ -1,16 +0,0 @@ @@ -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});
}

36
win_text_editor/lib/app/providers/editor_provider.dart

@ -1,17 +1,22 @@ @@ -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<EditorTab> _tabs = [];
final List<EditorTab> _tabs = [];
String? _activeTabId;
List<EditorTab> 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 { @@ -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});
}

90
win_text_editor/lib/app/widgets/editor_pane.dart

@ -1,80 +1,54 @@ @@ -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<EditorProvider>(context);
final provider = Provider.of<EditorProvider>(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<EditorProvider>(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<EditorProvider>(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 { @@ -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),
],

114
win_text_editor/lib/app/widgets/file_explorer.dart

@ -6,6 +6,8 @@ import '../models/file_node.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 { @@ -14,11 +16,13 @@ class FileExplorer extends StatefulWidget {
}
class _FileExplorerState extends State<FileExplorer> {
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<FileExplorer> { @@ -36,6 +40,28 @@ class _FileExplorerState extends State<FileExplorer> {
}
}
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<FileProvider>(context, listen: false);
if (node.isDirectory) {
await fileProvider.loadDirectoryContents(node);
} else {
//
//
// final editorProvider = Provider.of<EditorProvider>(context, listen: false);
// editorProvider.openFile(node.path);
}
}
@override
Widget build(BuildContext context) {
final fileProvider = Provider.of<FileProvider>(context);
@ -45,48 +71,64 @@ class _FileExplorerState extends State<FileExplorer> { @@ -45,48 +71,64 @@ class _FileExplorerState extends State<FileExplorer> {
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<FileNode> nodes) {
int maxDepth = 0;
for (final node in nodes) {
if (node.isDirectory && node.isExpanded) {
maxDepth = max(maxDepth, _getMaxDepth(node.children) + 1);
}
}
return maxDepth;
}
}
//

38
win_text_editor/lib/app/widgets/template_parser.dart

@ -1,38 +0,0 @@ @@ -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<TemplateParser> createState() => _TemplateParserState();
}
class _TemplateParserState extends State<TemplateParser> {
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;
// });
// },
// ),
);
}
}

181
win_text_editor/lib/app/widgets/text_editor.dart

@ -1,181 +0,0 @@ @@ -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<String>? onContentChanged;
const TextEditor({
Key? key,
this.initialContent,
this.editorTitle = '源文本',
this.showToolbar = true,
this.onContentChanged,
}) : super(key: key);
@override
State<TextEditor> createState() => _TextEditorState();
}
class _TextEditorState extends State<TextEditor> {
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<void> _openFile() async {
const String mockFileContent = """这是从文件加载的示例文本:
1
2
3""";
setState(() {
_textController.text = mockFileContent;
_currentFileName = "示例文件.txt";
});
}
Future<void> _copyToClipboard() async {
if (_textController.text.isNotEmpty) {
await Clipboard.setData(ClipboardData(text: _textController.text));
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('已复制全部文本到剪贴板')));
}
}
}
Future<void> _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();
}
}

96
win_text_editor/lib/app/widgets/text_tab.dart

@ -0,0 +1,96 @@ @@ -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<EditorProvider>(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<void> _openFile(BuildContext context, String tabId) async {
final provider = Provider.of<EditorProvider>(context, listen: false);
// 使
const mockContent = "从文件加载的示例文本...";
provider.updateContent(tabId, mockContent);
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('已加载文件内容')));
}
//
Future<void> _copyToClipboard(BuildContext context, String content) async {
await Clipboard.setData(ClipboardData(text: content));
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('已复制到剪贴板')));
}
}
//
Future<void> _saveFile(BuildContext context, String content) async {
// 使
if (context.mounted) {
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text('已保存 ${content.length} 个字符')));
}
}
}

106
win_text_editor/pubspec.lock

@ -6,7 +6,7 @@ packages: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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:

Loading…
Cancel
Save