添加webdav网络超时处理

This commit is contained in:
DelLevin-Home
2026-07-06 03:09:56 +08:00
parent 408c79ed40
commit cbe3f8dec7
2 changed files with 49 additions and 26 deletions

View File

@@ -53,6 +53,9 @@ class WebDAVService {
// 默认自动同步间隔(分钟) // 默认自动同步间隔(分钟)
static const int _defaultAutoSyncInterval = 5; static const int _defaultAutoSyncInterval = 5;
// HTTP 请求超时
static const Duration _httpTimeout = Duration(seconds: 30);
Map<String, String>? _cachedConfig; Map<String, String>? _cachedConfig;
Timer? _autoSyncTimer; Timer? _autoSyncTimer;
bool _isAutoSyncEnabled = false; bool _isAutoSyncEnabled = false;
@@ -426,7 +429,7 @@ class WebDAVService {
request.headers['Content-Type'] = 'application/zip'; request.headers['Content-Type'] = 'application/zip';
request.bodyBytes = bytes; request.bodyBytes = bytes;
var response = await client.send(request); var response = await client.send(request).timeout(_httpTimeout);
// 处理重定向 // 处理重定向
if (response.statusCode == 301 || response.statusCode == 302 || if (response.statusCode == 301 || response.statusCode == 302 ||
@@ -437,7 +440,7 @@ class WebDAVService {
request.headers['Authorization'] = _basicAuth(username, password); request.headers['Authorization'] = _basicAuth(username, password);
request.headers['Content-Type'] = 'application/zip'; request.headers['Content-Type'] = 'application/zip';
request.bodyBytes = bytes; request.bodyBytes = bytes;
response = await client.send(request); response = await client.send(request).timeout(_httpTimeout);
} }
} }
@@ -461,7 +464,7 @@ class WebDAVService {
var request = http.Request('GET', Uri.parse(url)); var request = http.Request('GET', Uri.parse(url));
request.headers['Authorization'] = _basicAuth(username, password); request.headers['Authorization'] = _basicAuth(username, password);
var response = await client.send(request); var response = await client.send(request).timeout(_httpTimeout);
// 处理重定向 // 处理重定向
if (response.statusCode == 301 || response.statusCode == 302 || if (response.statusCode == 301 || response.statusCode == 302 ||
@@ -470,7 +473,7 @@ class WebDAVService {
if (location != null) { if (location != null) {
request = http.Request('GET', Uri.parse(location)); request = http.Request('GET', Uri.parse(location));
request.headers['Authorization'] = _basicAuth(username, password); request.headers['Authorization'] = _basicAuth(username, password);
response = await client.send(request); response = await client.send(request).timeout(_httpTimeout);
} }
} }
@@ -508,7 +511,7 @@ class WebDAVService {
var request = http.Request('HEAD', Uri.parse(zipUrl)); var request = http.Request('HEAD', Uri.parse(zipUrl));
request.headers['Authorization'] = _basicAuth(username, password); request.headers['Authorization'] = _basicAuth(username, password);
var response = await client.send(request); var response = await client.send(request).timeout(_httpTimeout);
// 处理重定向 // 处理重定向
if (response.statusCode == 301 || response.statusCode == 302 || if (response.statusCode == 301 || response.statusCode == 302 ||
@@ -517,7 +520,7 @@ class WebDAVService {
if (location != null) { if (location != null) {
request = http.Request('HEAD', Uri.parse(location)); request = http.Request('HEAD', Uri.parse(location));
request.headers['Authorization'] = _basicAuth(username, password); request.headers['Authorization'] = _basicAuth(username, password);
response = await client.send(request); response = await client.send(request).timeout(_httpTimeout);
} }
} }
@@ -551,7 +554,7 @@ class WebDAVService {
var request = http.Request('HEAD', Uri.parse(url)); var request = http.Request('HEAD', Uri.parse(url));
request.headers['Authorization'] = _basicAuth(username, password); request.headers['Authorization'] = _basicAuth(username, password);
var response = await client.send(request); var response = await client.send(request).timeout(_httpTimeout);
// 处理重定向 // 处理重定向
if (response.statusCode == 301 || response.statusCode == 302 || if (response.statusCode == 301 || response.statusCode == 302 ||
@@ -560,7 +563,7 @@ class WebDAVService {
if (location != null) { if (location != null) {
request = http.Request('HEAD', Uri.parse(location)); request = http.Request('HEAD', Uri.parse(location));
request.headers['Authorization'] = _basicAuth(username, password); request.headers['Authorization'] = _basicAuth(username, password);
response = await client.send(request); response = await client.send(request).timeout(_httpTimeout);
} }
} }

View File

@@ -30,16 +30,40 @@ class _CustomDrawerState extends State<CustomDrawer> {
String _version = '0.1.5'; String _version = '0.1.5';
// 热力图缓存 // 热力图缓存
List<Movie>? _cachedMovies; int _cachedMoviesHash = 0;
List<Book>? _cachedBooks; int _cachedBooksHash = 0;
List<Note>? _cachedNotes; int _cachedNotesHash = 0;
List<Game>? _cachedGames; int _cachedGamesHash = 0;
Map<DateTime, int>? _cachedDailyCounts; Map<DateTime, int>? _cachedDailyCounts;
int? _cachedMaxCount; int? _cachedMaxCount;
// 最近添加缓存 // 最近添加缓存
List<_RecentItem>? _cachedRecentItems; List<_RecentItem>? _cachedRecentItems;
/// 用列表长度 + 首末元素ID生成轻量哈希避免 identical() 在 Provider 返回新实例时永远失败
int _listHash<T>(List<T> list) {
if (list.isEmpty) return 0;
final first = list.first;
final last = list.last;
return Object.hash(list.length, first, last);
}
bool _isHeatmapCacheValid(List<Movie> movies, List<Book> books, List<Note> notes, List<Game> games) {
return _cachedDailyCounts != null &&
_cachedMoviesHash == _listHash(movies) &&
_cachedBooksHash == _listHash(books) &&
_cachedNotesHash == _listHash(notes) &&
_cachedGamesHash == _listHash(games);
}
bool _isRecentCacheValid(List<Movie> movies, List<Book> books, List<Note> notes, List<Game> games) {
return _cachedRecentItems != null &&
_cachedMoviesHash == _listHash(movies) &&
_cachedBooksHash == _listHash(books) &&
_cachedNotesHash == _listHash(notes) &&
_cachedGamesHash == _listHash(games);
}
@override @override
void initState() { void initState() {
super.initState(); super.initState();
@@ -264,11 +288,7 @@ class _CustomDrawerState extends State<CustomDrawer> {
// ─── 热力图缓存计算 ─── // ─── 热力图缓存计算 ───
(int, Map<DateTime, int>) _computeDailyCounts(List<Movie> movies, List<Book> books, List<Note> notes, List<Game> games) { (int, Map<DateTime, int>) _computeDailyCounts(List<Movie> movies, List<Book> books, List<Note> notes, List<Game> games) {
if (identical(movies, _cachedMovies) && if (_isHeatmapCacheValid(movies, books, notes, games)) {
identical(books, _cachedBooks) &&
identical(notes, _cachedNotes) &&
identical(games, _cachedGames) &&
_cachedDailyCounts != null) {
return (_cachedMaxCount!, _cachedDailyCounts!); return (_cachedMaxCount!, _cachedDailyCounts!);
} }
@@ -296,21 +316,17 @@ class _CustomDrawerState extends State<CustomDrawer> {
} }
if (maxCount == 0) maxCount = 1; if (maxCount == 0) maxCount = 1;
_cachedMovies = movies; _cachedMoviesHash = _listHash(movies);
_cachedBooks = books; _cachedBooksHash = _listHash(books);
_cachedNotes = notes; _cachedNotesHash = _listHash(notes);
_cachedGames = games; _cachedGamesHash = _listHash(games);
_cachedDailyCounts = dailyCounts; _cachedDailyCounts = dailyCounts;
_cachedMaxCount = maxCount; _cachedMaxCount = maxCount;
return (maxCount, dailyCounts); return (maxCount, dailyCounts);
} }
List<_RecentItem> _computeRecentItems(List<Movie> movies, List<Book> books, List<Note> notes, List<Game> games) { List<_RecentItem> _computeRecentItems(List<Movie> movies, List<Book> books, List<Note> notes, List<Game> games) {
if (identical(movies, _cachedMovies) && if (_isRecentCacheValid(movies, books, notes, games)) {
identical(books, _cachedBooks) &&
identical(notes, _cachedNotes) &&
identical(games, _cachedGames) &&
_cachedRecentItems != null) {
return _cachedRecentItems!; return _cachedRecentItems!;
} }
@@ -329,6 +345,10 @@ class _CustomDrawerState extends State<CustomDrawer> {
} }
items.sort((a, b) => b.date.compareTo(a.date)); items.sort((a, b) => b.date.compareTo(a.date));
_cachedMoviesHash = _listHash(movies);
_cachedBooksHash = _listHash(books);
_cachedNotesHash = _listHash(notes);
_cachedGamesHash = _listHash(games);
_cachedRecentItems = items; _cachedRecentItems = items;
return items; return items;
} }