import 'package:flutter/material.dart'; import 'package:flutter/foundation.dart'; import 'package:shared_preferences/shared_preferences.dart'; class SettingsProvider with ChangeNotifier { // Use 10.0.2.2 for Android emulator to access host's localhost static String get _defaultUrl => (defaultTargetPlatform == TargetPlatform.android && !kIsWeb) ? "http://10.0.2.2:8080" : "http://localhost:8080"; String _baseUrl = _defaultUrl; Color _themeColor = Colors.blue; ThemeMode _themeMode = ThemeMode.system; bool _livePreviewThumbnailsEnabled = false; Locale? _locale; String get baseUrl => _baseUrl; Color get themeColor => _themeColor; ThemeMode get themeMode => _themeMode; bool get livePreviewThumbnailsEnabled => _livePreviewThumbnailsEnabled; Locale? get locale => _locale; SettingsProvider() { _loadSettings(); } void _loadSettings() async { final prefs = await SharedPreferences.getInstance(); _baseUrl = prefs.getString('baseUrl') ?? _baseUrl; final colorValue = prefs.getInt('themeColor'); if (colorValue != null) { _themeColor = Color(colorValue); } final savedThemeMode = prefs.getString('themeMode'); if (savedThemeMode != null) { _themeMode = _themeModeFromString(savedThemeMode); } _livePreviewThumbnailsEnabled = prefs.getBool('livePreviewThumbnailsEnabled') ?? false; final languageCode = prefs.getString('languageCode'); final scriptCode = prefs.getString('scriptCode'); final countryCode = prefs.getString('countryCode'); if (languageCode != null) { _locale = Locale.fromSubtags( languageCode: languageCode, scriptCode: scriptCode, countryCode: countryCode, ); } notifyListeners(); } void setLocale(Locale? newLocale) async { _locale = newLocale; final prefs = await SharedPreferences.getInstance(); if (newLocale == null) { await prefs.remove('languageCode'); await prefs.remove('scriptCode'); await prefs.remove('countryCode'); } else { await prefs.setString('languageCode', newLocale.languageCode); if (newLocale.scriptCode != null) { await prefs.setString('scriptCode', newLocale.scriptCode!); } else { await prefs.remove('scriptCode'); } if (newLocale.countryCode != null) { await prefs.setString('countryCode', newLocale.countryCode!); } else { await prefs.remove('countryCode'); } } notifyListeners(); } void setBaseUrl(String url) async { _baseUrl = url; final prefs = await SharedPreferences.getInstance(); await prefs.setString('baseUrl', url); notifyListeners(); } void setThemeColor(Color color) async { _themeColor = color; final prefs = await SharedPreferences.getInstance(); await prefs.setInt('themeColor', color.toARGB32()); notifyListeners(); } void setThemeMode(ThemeMode mode) async { _themeMode = mode; final prefs = await SharedPreferences.getInstance(); await prefs.setString('themeMode', mode.name); notifyListeners(); } void setLivePreviewThumbnailsEnabled(bool enabled) async { _livePreviewThumbnailsEnabled = enabled; final prefs = await SharedPreferences.getInstance(); await prefs.setBool('livePreviewThumbnailsEnabled', enabled); notifyListeners(); } // Also provide the RTMP URL based on the same hostname String get rtmpUrl { final uri = Uri.parse(_baseUrl); return "rtmp://${uri.host}:1935/live"; } String playbackUrl(String roomId, {String? quality}) { final uri = Uri.parse(_baseUrl); final normalizedQuality = quality?.trim().toLowerCase(); if (kIsWeb) { return uri .replace( path: '/live/$roomId', queryParameters: normalizedQuality == null || normalizedQuality.isEmpty ? null : {'quality': normalizedQuality}, ) .toString(); } if (normalizedQuality == null || normalizedQuality.isEmpty) { return "$rtmpUrl/$roomId"; } return "$rtmpUrl/$roomId/$normalizedQuality"; } String thumbnailUrl(String roomId, {String? cacheBuster}) { final uri = Uri.parse(_baseUrl); return uri .replace( path: '/api/rooms/$roomId/thumbnail', queryParameters: cacheBuster == null ? null : {'t': cacheBuster}, ) .toString(); } ThemeMode _themeModeFromString(String value) { switch (value) { case 'light': return ThemeMode.light; case 'dark': return ThemeMode.dark; default: return ThemeMode.system; } } }