feat: Windows compatibility (#836)

* feat: win compatibility

* fix

* fix: uptime parse

* opt.: linux uptime accuracy

* fix: windows temperature fetching

* opt.

* opt.: powershell exec

* refactor: address PR review feedback and improve code quality

### Major Improvements:
- **Refactored Windows status parsing**: Broke down large `_getWindowsStatus` method into 13 smaller, focused helper methods for better maintainability and readability
- **Extracted system detection logic**: Created dedicated `SystemDetector` helper class to separate OS detection concerns from ServerProvider
- **Improved concurrency handling**: Implemented proper synchronization for server updates using Future-based locks to prevent race conditions

### Bug Fixes:
- **Fixed CPU percentage parsing**: Removed incorrect '*100' multiplication in BSD CPU parsing (values were already percentages)
- **Enhanced memory parsing**: Added validation and error handling to BSD memory fallback parsing with proper logging
- **Improved uptime parsing**: Added support for multiple Windows date formats and robust error handling with validation
- **Fixed division by zero**: Added safety checks in Swap.usedPercent getter

### Code Quality Enhancements:
- **Added comprehensive documentation**: Documented Windows CPU counter limitations and approach
- **Strengthened error handling**: Added detailed logging and validation throughout parsing methods
- **Improved robustness**: Enhanced BSD CPU parsing with percentage validation and warnings
- **Better separation of concerns**: Each parsing method now has single responsibility

### Files Changed:
- `lib/data/helper/system_detector.dart` (new): System detection helper
- `lib/data/model/server/cpu.dart`: Fixed percentage parsing and added validation
- `lib/data/model/server/memory.dart`: Enhanced fallback parsing and division-by-zero protection
- `lib/data/model/server/server_status_update_req.dart`: Refactored into 13 focused parsing methods
- `lib/data/provider/server.dart`: Improved synchronization and extracted system detection

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor: parse & shell fn struct

---------

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
lollipopkit🏳️‍⚧️
2025-08-08 16:56:36 +08:00
committed by GitHub
parent 46a12bc844
commit 3a615449e3
103 changed files with 9591 additions and 1906 deletions

View File

@@ -16,19 +16,14 @@ class SSHTabPage extends StatefulWidget {
@override
State<SSHTabPage> createState() => _SSHTabPageState();
static const route = AppRouteNoArg(
page: SSHTabPage.new,
path: '/ssh',
);
static const route = AppRouteNoArg(page: SSHTabPage.new, path: '/ssh');
}
typedef _TabMap = Map<String, ({Widget page, FocusNode? focus})>;
class _SSHTabPageState extends State<SSHTabPage>
with TickerProviderStateMixin, AutomaticKeepAliveClientMixin {
late final _TabMap _tabMap = {
libL10n.add: (page: _AddPage(onTapInitCard: _onTapInitCard), focus: null),
};
late final _TabMap _tabMap = {libL10n.add: (page: _AddPage(onTapInitCard: _onTapInitCard), focus: null)};
final _pageCtrl = PageController();
final _fabVN = 0.vn;
final _tabRN = RNode();
@@ -48,12 +43,7 @@ class _SSHTabPageState extends State<SSHTabPage>
appBar: PreferredSizeListenBuilder(
listenable: _tabRN,
builder: () {
return _TabBar(
idxVN: _fabVN,
map: _tabMap,
onTap: _onTapTab,
onClose: _onTapClose,
);
return _TabBar(idxVN: _fabVN, map: _tabMap, onTap: _onTapTab, onClose: _onTapClose);
},
),
body: _buildBody(),
@@ -159,12 +149,7 @@ extension on _SSHTabPageState {
}
final class _TabBar extends StatelessWidget implements PreferredSizeWidget {
const _TabBar({
required this.idxVN,
required this.map,
required this.onTap,
required this.onClose,
});
const _TabBar({required this.idxVN, required this.map, required this.onTap, required this.onClose});
final ValueListenable<int> idxVN;
final _TabMap map;
@@ -188,10 +173,7 @@ final class _TabBar extends StatelessWidget implements PreferredSizeWidget {
itemBuilder: (_, idx) => _buildItem(idx),
separatorBuilder: (_, _) => Padding(
padding: const EdgeInsets.symmetric(vertical: 17),
child: Container(
color: const Color.fromARGB(61, 158, 158, 158),
width: 3,
),
child: Container(color: const Color.fromARGB(61, 158, 158, 158), width: 3),
),
);
},
@@ -242,10 +224,7 @@ final class _TabBar extends StatelessWidget implements PreferredSizeWidget {
width: selected ? kWideWidth : kNarrowWidth,
duration: Durations.medium3,
curve: Curves.fastEaseInToSlowEaseOut,
child: OverflowBox(
maxWidth: selected ? kWideWidth : null,
child: btn,
),
child: OverflowBox(maxWidth: selected ? kWideWidth : null, child: btn),
);
}
@@ -280,9 +259,7 @@ class _AddPage extends StatelessWidget {
return ServerProvider.serverOrder.listenVal((order) {
if (order.isEmpty) {
return Center(
child: Text(libL10n.empty, textAlign: TextAlign.center),
);
return Center(child: Text(libL10n.empty, textAlign: TextAlign.center));
}
// Custom grid
@@ -316,7 +293,7 @@ class _AddPage extends StatelessWidget {
overflow: TextOverflow.ellipsis,
),
),
const Icon(Icons.chevron_right)
const Icon(Icons.chevron_right),
],
),
),