87 lines
2.4 KiB
Dart
87 lines
2.4 KiB
Dart
// Author: fruit.com.cn
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
import 'app_config.dart';
|
|
|
|
/// Debug-only runtime server endpoint persisted outside build-time defines.
|
|
abstract final class ServerEndpoint {
|
|
/// Preference key used for the runtime server address.
|
|
static const String preferenceKey = 'dev.api_base_url';
|
|
|
|
/// Returns a normalized http(s) URL, or null for invalid input.
|
|
static String? normalize(String? raw) {
|
|
final value = raw?.trim() ?? '';
|
|
final uri = Uri.tryParse(value);
|
|
if (uri == null ||
|
|
(uri.scheme != 'http' && uri.scheme != 'https') ||
|
|
uri.host.isEmpty) {
|
|
return null;
|
|
}
|
|
return value.replaceFirst(RegExp(r'/+$'), '');
|
|
}
|
|
|
|
/// Resolves runtime > dart-define > default using normalized valid values.
|
|
static String resolve({
|
|
required String? stored,
|
|
required String compiled,
|
|
required String fallback,
|
|
}) {
|
|
return normalize(stored) ??
|
|
normalize(compiled) ??
|
|
normalize(fallback) ??
|
|
fallback;
|
|
}
|
|
|
|
/// Loads the persisted override before the app creates its ApiClient.
|
|
///
|
|
/// In release builds this returns immediately without reading preferences.
|
|
static Future<void> load({
|
|
bool debug = kDebugMode,
|
|
SharedPreferencesAsync? preferences,
|
|
}) async {
|
|
if (!debug) return;
|
|
try {
|
|
final prefs = preferences ?? SharedPreferencesAsync();
|
|
final stored = await prefs.getString(preferenceKey);
|
|
AppConfig.applyRuntimeBaseUrl(
|
|
resolve(
|
|
stored: stored,
|
|
compiled: AppConfig.compiledBaseUrl,
|
|
fallback: AppConfig.defaultBaseUrl,
|
|
),
|
|
);
|
|
} catch (_) {
|
|
AppConfig.clearRuntimeBaseUrl();
|
|
}
|
|
}
|
|
|
|
/// Persists a normalized runtime endpoint.
|
|
static Future<bool> save(
|
|
String raw, {
|
|
SharedPreferencesAsync? preferences,
|
|
}) async {
|
|
final normalized = normalize(raw);
|
|
if (normalized == null) return false;
|
|
try {
|
|
await (preferences ?? SharedPreferencesAsync()).setString(
|
|
preferenceKey,
|
|
normalized,
|
|
);
|
|
return true;
|
|
} catch (_) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// Removes the persisted runtime endpoint.
|
|
static Future<void> clear({SharedPreferencesAsync? preferences}) async {
|
|
try {
|
|
await (preferences ?? SharedPreferencesAsync()).remove(preferenceKey);
|
|
} catch (_) {
|
|
// Clearing an optional developer override is best effort.
|
|
}
|
|
}
|
|
}
|