2 changed files with 0 additions and 173 deletions
@ -1,142 +0,0 @@ |
|||||||
import 'dart:math'; |
|
||||||
|
|
||||||
import 'package:flutter/material.dart'; |
|
||||||
import 'package:win_text_editor/framework/controllers/logger.dart'; |
|
||||||
|
|
||||||
class EditorProvider with ChangeNotifier { |
|
||||||
final List<EditorTab> _tabs = []; |
|
||||||
String? _activeTabId; |
|
||||||
bool _isLoading = false; |
|
||||||
|
|
||||||
List<EditorTab> get tabs => _tabs; |
|
||||||
String? get activeTabId => _activeTabId; |
|
||||||
bool get isLoading => _isLoading; |
|
||||||
|
|
||||||
int _templateTabCounter = 1; |
|
||||||
|
|
||||||
final Map<String, bool> _tabLoadingStates = {}; |
|
||||||
final Map<String, int> _tabLoadedChunks = {}; |
|
||||||
|
|
||||||
bool isTabLoading(String tabId) => _tabLoadingStates[tabId] ?? false; |
|
||||||
int getLoadedChunks(String tabId) => _tabLoadedChunks[tabId] ?? 0; |
|
||||||
|
|
||||||
EditorTab? get activeTab { |
|
||||||
if (_activeTabId == null) return null; |
|
||||||
try { |
|
||||||
return _tabs.firstWhere((tab) => tab.id == _activeTabId); |
|
||||||
} catch (e) { |
|
||||||
Logger().error("找不到活动选项卡: $_activeTabId", source: 'EditorProvider'); |
|
||||||
return null; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void addTab() { |
|
||||||
final tabId = DateTime.now().millisecondsSinceEpoch.toString(); |
|
||||||
_tabs.add( |
|
||||||
EditorTab( |
|
||||||
id: tabId, |
|
||||||
title: '模板解析[$_templateTabCounter]', |
|
||||||
chunks: [], // 显式初始化 |
|
||||||
content: '', |
|
||||||
), |
|
||||||
); |
|
||||||
_templateTabCounter++; |
|
||||||
_activeTabId = tabId; |
|
||||||
notifyListeners(); |
|
||||||
} |
|
||||||
|
|
||||||
void closeTab(String tabId) { |
|
||||||
Logger().info('关闭选项卡: $tabId'); |
|
||||||
_tabs.removeWhere((tab) => tab.id == tabId); |
|
||||||
if (_activeTabId == tabId) { |
|
||||||
_activeTabId = _tabs.isNotEmpty ? _tabs.last.id : null; |
|
||||||
} |
|
||||||
notifyListeners(); |
|
||||||
} |
|
||||||
|
|
||||||
void setActiveTab(String tabId) { |
|
||||||
Logger().info('设置活动选项卡: $tabId'); |
|
||||||
_activeTabId = tabId; |
|
||||||
notifyListeners(); |
|
||||||
} |
|
||||||
|
|
||||||
Future<void> updateContent(String tabId, String content, String? name) async { |
|
||||||
_isLoading = true; |
|
||||||
notifyListeners(); |
|
||||||
|
|
||||||
try { |
|
||||||
final index = _tabs.indexWhere((t) => t.id == tabId); |
|
||||||
if (index == -1) throw Exception("Tab not found"); |
|
||||||
|
|
||||||
_tabs[index] = EditorTab( |
|
||||||
id: _tabs[index].id, |
|
||||||
title: _tabs[index].title, |
|
||||||
chunks: content.split('\n'), // 同步更新 chunks |
|
||||||
fileName: name ?? _tabs[index].fileName, |
|
||||||
content: content, |
|
||||||
); |
|
||||||
} finally { |
|
||||||
_isLoading = false; |
|
||||||
notifyListeners(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// 在 EditorProvider 中修改文件加载逻辑 |
|
||||||
Future<void> updateContentInChunks(String tabId, String fullContent, String? fileName) async { |
|
||||||
final lines = fullContent.split('\n'); |
|
||||||
const linesPerChunk = 1000; // 每1000行一个块 |
|
||||||
|
|
||||||
_tabLoadingStates[tabId] = true; |
|
||||||
notifyListeners(); |
|
||||||
|
|
||||||
try { |
|
||||||
// 清空现有内容 |
|
||||||
final index = _tabs.indexWhere((t) => t.id == tabId); |
|
||||||
_tabs[index] = EditorTab( |
|
||||||
id: tabId, |
|
||||||
title: fileName ?? _tabs[index].title, |
|
||||||
chunks: [], |
|
||||||
fileName: fileName, |
|
||||||
); |
|
||||||
|
|
||||||
// 分块加载行 |
|
||||||
for (int i = 0; i < lines.length; i += linesPerChunk) { |
|
||||||
if (!_tabLoadingStates[tabId]!) break; // 检查是否取消 |
|
||||||
|
|
||||||
final chunkLines = lines.sublist(i, min(i + linesPerChunk, lines.length)); |
|
||||||
_tabs[index].chunks.addAll(chunkLines); |
|
||||||
|
|
||||||
notifyListeners(); |
|
||||||
await Future.delayed(Duration.zero); // 让UI更新 |
|
||||||
} |
|
||||||
} finally { |
|
||||||
_tabLoadingStates.remove(tabId); |
|
||||||
notifyListeners(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void cancelLoading(String tabId) { |
|
||||||
_tabLoadingStates[tabId] = false; |
|
||||||
notifyListeners(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
class EditorTab { |
|
||||||
final String id; |
|
||||||
String title; |
|
||||||
List<String> chunks; // 移除可空标记,改为非空 |
|
||||||
String? fileName; |
|
||||||
bool isHighlightEnabled; |
|
||||||
String content; |
|
||||||
|
|
||||||
EditorTab({ |
|
||||||
required this.id, |
|
||||||
required this.title, |
|
||||||
List<String>? chunks, // 参数可选,但类内部非空 |
|
||||||
this.fileName, |
|
||||||
this.isHighlightEnabled = true, |
|
||||||
this.content = '', |
|
||||||
}) : chunks = chunks ?? []; // 默认值为空列表 |
|
||||||
|
|
||||||
String get fullContent => chunks.join('\n'); // 用换行符连接 |
|
||||||
} |
|
@ -1,31 +0,0 @@ |
|||||||
class SyntaxService { |
|
||||||
static String detectFileType(String fileName) { |
|
||||||
final extension = fileName.split('.').last.toLowerCase(); |
|
||||||
|
|
||||||
switch (extension) { |
|
||||||
case 'dart': |
|
||||||
return 'dart'; |
|
||||||
case 'java': |
|
||||||
return 'java'; |
|
||||||
case 'js': |
|
||||||
return 'javascript'; |
|
||||||
case 'py': |
|
||||||
return 'python'; |
|
||||||
case 'html': |
|
||||||
return 'html'; |
|
||||||
case 'css': |
|
||||||
return 'css'; |
|
||||||
case 'json': |
|
||||||
return 'json'; |
|
||||||
case 'xml': |
|
||||||
return 'xml'; |
|
||||||
case 'md': |
|
||||||
return 'markdown'; |
|
||||||
case 'yaml': |
|
||||||
case 'yml': |
|
||||||
return 'yaml'; |
|
||||||
default: |
|
||||||
return 'text'; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
Loading…
Reference in new issue