Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reestructure Settings #217

Merged
merged 26 commits into from
Mar 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
94b4de1
feat: Add all settings options
bdlukaa Feb 18, 2024
0c6b5b9
feat: Organize General tab
bdlukaa Feb 18, 2024
bc452e6
feat: Add all options to server and devices
bdlukaa Feb 18, 2024
a0dcb85
feat: Events and downloads settings
bdlukaa Feb 18, 2024
6d3eff7
feat: Organize Application section
bdlukaa Feb 18, 2024
a0aadd9
feat: Organize sections
bdlukaa Feb 18, 2024
a20422a
feat: Update Updates section
bdlukaa Feb 19, 2024
baef9bb
feat: Add Advanced Options section
bdlukaa Feb 19, 2024
65dfbef
feat: Sections on small screens (mobile)
bdlukaa Feb 19, 2024
461d96d
feat: Privacy and Security field
bdlukaa Feb 19, 2024
13504fc
feat: Add Acessibility section under Application section
bdlukaa Feb 19, 2024
99d43a5
chore: Move tiles to their respective section
bdlukaa Feb 19, 2024
98ce912
feat: Reorganize Settings folders
bdlukaa Feb 19, 2024
03cc41b
fix: Make use of the `SubHeader` widget on the sections
bdlukaa Feb 21, 2024
39a1af4
fix: Basic settings functionality
bdlukaa Feb 28, 2024
a391498
fix: Downloads and Layouts settings
bdlukaa Feb 28, 2024
7afe8cc
fix: Correctly assign the default downloads directory
bdlukaa Feb 28, 2024
8d4bd14
feat: restore the default settings
bdlukaa Feb 28, 2024
3cedbbb
fix: Do not throw error if hls errored
bdlukaa Feb 29, 2024
d931d6a
fix: Analysis issues
bdlukaa Mar 2, 2024
d601312
feat: Allow async default values
bdlukaa Mar 2, 2024
b234d88
fix: Remove migration from old storage system;
bdlukaa Mar 2, 2024
3b35393
feat: Do not show options that do not have any effect yet
bdlukaa Mar 3, 2024
fcfd462
feat: Update SettingsProvider when the value of an option is updated
bdlukaa Mar 3, 2024
6ef5a50
feat: Update all the options values in the settings
bdlukaa Mar 3, 2024
bf45104
fix: Fallback to the default value if data is corrupted
bdlukaa Mar 3, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions lib/firebase_messaging_background_handler.dart
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ Future<void> _firebaseMessagingHandler(RemoteMessage message) async {
await configureStorage();
await ServersProvider.ensureInitialized();
await SettingsProvider.ensureInitialized();
if (SettingsProvider.instance.snoozedUntil.isAfter(DateTime.now())) {
if (SettingsProvider.instance.kSnoozeNotificationsUntil.value
.isAfter(DateTime.now())) {
debugPrint(
'SettingsProvider.instance.snoozedUntil.isAfter(DateTime.now())',
);
Expand Down Expand Up @@ -192,7 +193,7 @@ Future<void> _backgroundClickAction(ReceivedAction action) async {
if (action.buttonKeyPressed.isEmpty) {
debugPrint('action.buttonKeyPressed.isEmpty');
// Fetch device & server details to show the [DeviceFullscreenViewer].
if (SettingsProvider.instance.notificationClickBehavior ==
if (SettingsProvider.instance.kNotificationClickBehavior.value ==
NotificationClickBehavior.showFullscreenCamera) {
final eventType = action.payload!['eventType'];
final serverUUID = action.payload!['serverId'];
Expand Down Expand Up @@ -264,7 +265,8 @@ Future<void> _backgroundClickAction(ReceivedAction action) async {
},
);
debugPrint(DateTime.now().add(duration).toString());
SettingsProvider.instance.snoozedUntil = DateTime.now().add(duration);
SettingsProvider.instance.kSnoozeNotificationsUntil.value =
DateTime.now().add(duration);
if (action.id != null) {
AwesomeNotifications().dismiss(action.id!);
}
Expand All @@ -282,7 +284,8 @@ abstract class FirebaseConfiguration {
);
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingHandler);
FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
if (SettingsProvider.instance.snoozedUntil.isAfter(DateTime.now())) {
if (SettingsProvider.instance.kSnoozeNotificationsUntil.value
.isAfter(DateTime.now())) {
debugPrint(
'SettingsProvider.instance.snoozedUntil.isAfter(DateTime.now())',
);
Expand Down Expand Up @@ -431,7 +434,7 @@ abstract class FirebaseConfiguration {
FirebaseMessaging.instance.onTokenRefresh.listen(
(token) async {
debugPrint('[FirebaseMessaging.instance.onTokenRefresh]: $token');
storage.add({kHiveNotificationToken: token});
storage.add({kStorageNotificationToken: token});
for (final server in ServersProvider.instance.servers) {
API.instance.registerNotificationToken(
await API.instance.checkServerCredentials(server),
Expand All @@ -447,10 +450,10 @@ abstract class FirebaseConfiguration {
if (token != null) {
final data = await tryReadStorage(() => storage.read());
// Do not proceed, if token is already saved.
if (data[kHiveNotificationToken] == token) {
if (data[kStorageNotificationToken] == token) {
return;
}
await storage.add({kHiveNotificationToken: token});
await storage.add({kStorageNotificationToken: token});
for (final server in ServersProvider.instance.servers) {
API.instance.registerNotificationToken(
await API.instance.checkServerCredentials(server),
Expand Down
4 changes: 2 additions & 2 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ class _UnityAppState extends State<UnityApp>
debugShowCheckedModeBanner: false,
navigatorKey: navigatorKey,
navigatorObservers: [NObserver()],
locale: settings.locale,
locale: settings.kLanguageCode.value,
localizationsDelegates: const [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
Expand All @@ -315,7 +315,7 @@ class _UnityAppState extends State<UnityApp>
LocaleNamesLocalizationsDelegate(),
],
supportedLocales: AppLocalizations.supportedLocales,
themeMode: settings.themeMode,
themeMode: settings.kThemeMode.value,
theme: createTheme(brightness: Brightness.light),
darkTheme: createTheme(brightness: Brightness.dark),
initialRoute: '/',
Expand Down
24 changes: 14 additions & 10 deletions lib/models/device.dart
Original file line number Diff line number Diff line change
Expand Up @@ -265,17 +265,21 @@ class Device {
queryParameters: data,
);

var response = await API.client.get(uri);

if (response.statusCode == 200) {
var ret = json.decode(response.body) as Map;

if (ret['status'] == 6) {
var hlsLink = ret['msg'][0];
return Uri.encodeFull(hlsLink);
try {
var response = await API.client.get(uri);

if (response.statusCode == 200) {
var ret = json.decode(response.body) as Map;

if (ret['status'] == 6) {
var hlsLink = ret['msg'][0];
return Uri.encodeFull(hlsLink);
}
} else {
debugPrint('Request failed with status: ${response.statusCode}');
}
} else {
debugPrint('Request failed with status: ${response.statusCode}');
} catch (error, stacktrace) {
debugPrint('Failed to get HLS url($uri): $error, $stacktrace');
}

return hlsURL;
Expand Down
11 changes: 6 additions & 5 deletions lib/providers/desktop_view_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class DesktopViewProvider extends UnityProvider {
static Future<DesktopViewProvider> ensureInitialized() async {
instance = DesktopViewProvider._();
await instance.initialize();
debugPrint('DesktopViewProvider initialized');
return instance;
}

Expand All @@ -60,7 +61,7 @@ class DesktopViewProvider extends UnityProvider {
@override
Future<void> initialize() async {
await tryReadStorage(
() => initializeStorage(desktopView, kHiveDesktopLayouts),
() => initializeStorage(desktopView, kStorageDesktopLayouts),
);
await Future.wait(
currentLayout.devices.map<Future>((device) {
Expand All @@ -85,9 +86,9 @@ class DesktopViewProvider extends UnityProvider {
Future<void> save({bool notifyListeners = true}) async {
try {
await desktopView.write({
kHiveDesktopLayouts:
kStorageDesktopLayouts:
jsonEncode(layouts.map((layout) => layout.toMap()).toList()),
kHiveDesktopCurrentLayout: _currentLayout,
kStorageDesktopCurrentLayout: _currentLayout,
});
} catch (error, stackTrace) {
debugPrint('Failed to save desktop view:\n $error\n$stackTrace');
Expand All @@ -103,14 +104,14 @@ class DesktopViewProvider extends UnityProvider {

layouts = ((await compute(
jsonDecode,
data[kHiveDesktopLayouts] as String,
data[kStorageDesktopLayouts] as String,
) ??
[]) as List)
.cast<Map>()
.map<Layout>((item) {
return Layout.fromMap(item.cast<String, dynamic>());
}).toList();
_currentLayout = data[kHiveDesktopCurrentLayout] ?? 0;
_currentLayout = data[kStorageDesktopCurrentLayout] ?? 0;

super.restore(notifyListeners: notifyListeners);
}
Expand Down
49 changes: 27 additions & 22 deletions lib/providers/downloads_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,6 @@ import 'package:flutter/foundation.dart';
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart';

import 'package:path_provider_platform_interface/path_provider_platform_interface.dart';
import 'package:path_provider_windows/path_provider_windows.dart'
hide WindowsKnownFolder;
// ignore: implementation_imports
import 'package:path_provider_windows/src/folders_stub.dart'
if (dart.library.ffi) 'package:path_provider_windows/src/folders.dart'
show WindowsKnownFolder;

class DownloadedEvent {
final Event event;
final String downloadPath;
Expand Down Expand Up @@ -100,25 +92,38 @@ class DownloadsManager extends UnityProvider {
static Future<DownloadsManager> ensureInitialized() async {
instance = DownloadsManager._();
await instance.initialize();
debugPrint('DownloadsManager initialized');
return instance;
}

static Future<Directory> get kDefaultDownloadsDirectory async {
Directory? dir;
if (PathProviderPlatform.instance is PathProviderWindows) {
final instance = PathProviderPlatform.instance as PathProviderWindows;
final videosPath =
// ignore: unnecessary_cast
await instance.getPath((WindowsKnownFolder as dynamic).Videos)
as String;
dir = Directory(path.join(videosPath, 'Bluecherry Client', 'Downloads'));
}
try {
if (!kIsWeb && defaultTargetPlatform == TargetPlatform.android) {
final dirs = await getExternalStorageDirectories(
type: StorageDirectory.downloads);
if (dirs?.isNotEmpty ?? false) dir = dirs!.first;
}

if (dir == null) {
if (dir == null) {
final downloadsDir = await getDownloadsDirectory();
if (downloadsDir != null) {
dir = Directory(path.join(downloadsDir.path, 'Bluecherry Client'));
}
}

if (dir == null) {
final docsDir = await getApplicationSupportDirectory();
dir = Directory(path.join(docsDir.path, 'downloads'));
}
} catch (error, stack) {
debugPrint('Failed to get default downloads directory: $error\n$stack');
final docsDir = await getApplicationSupportDirectory();
dir = Directory(path.join(docsDir.path, 'downloads'));
}

debugPrint('The default downloads is ${dir.path}');

return dir.create(recursive: true);
}

Expand Down Expand Up @@ -155,14 +160,14 @@ class DownloadsManager extends UnityProvider {
});

await tryReadStorage(
() => super.initializeStorage(downloads, kHiveDownloads));
() => super.initializeStorage(downloads, kStorageDownloads));
}

@override
Future<void> save({bool notifyListeners = true}) async {
try {
await downloads.write({
kHiveDownloads:
kStorageDownloads:
jsonEncode(downloadedEvents.map((de) => de.toJson()).toList()),
});
} catch (e) {
Expand All @@ -176,9 +181,9 @@ class DownloadsManager extends UnityProvider {
Future<void> restore({bool notifyListeners = true}) async {
final data = await tryReadStorage(() => downloads.read());

downloadedEvents = data[kHiveDownloads] == null
downloadedEvents = data[kStorageDownloads] == null
? []
: ((await compute(jsonDecode, data[kHiveDownloads] as String) ?? [])
: ((await compute(jsonDecode, data[kStorageDownloads] as String) ?? [])
as List)
.cast<Map>()
.map<DownloadedEvent>((item) {
Expand Down Expand Up @@ -225,7 +230,7 @@ class DownloadsManager extends UnityProvider {
downloading[event] = 0.0;
notifyListeners();

final dir = SettingsProvider.instance.downloadsDirectory;
final dir = SettingsProvider.instance.kDownloadsDirectory.value;
final fileName =
'event_${event.id}_${event.deviceID}_${event.server.name}.mp4';
final downloadPath = path.join(dir, fileName);
Expand Down
7 changes: 4 additions & 3 deletions lib/providers/events_playback_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,14 @@ class EventsProvider extends UnityProvider {
static Future<EventsProvider> ensureInitialized() async {
instance = EventsProvider._();
await instance.initialize();
debugPrint('EventsProvider initialized');
return instance;
}

@override
Future<void> initialize() {
return tryReadStorage(
() => super.initializeStorage(eventsPlayback, kHiveEventsPlayback));
() => super.initializeStorage(eventsPlayback, kStorageEventsPlayback));
}

/// The list of the device ids that are currently selected
Expand All @@ -50,7 +51,7 @@ class EventsProvider extends UnityProvider {
Future<void> save({bool notifyListeners = true}) async {
try {
await eventsPlayback.write({
kHiveEventsPlayback: jsonEncode(selectedIds),
kStorageEventsPlayback: jsonEncode(selectedIds),
});
} catch (e) {
debugPrint(e.toString());
Expand All @@ -65,7 +66,7 @@ class EventsProvider extends UnityProvider {
final data = await tryReadStorage(() => eventsPlayback.read());

selectedIds =
(jsonDecode(data[kHiveEventsPlayback]) as List).cast<String>();
(jsonDecode(data[kStorageEventsPlayback]) as List).cast<String>();

super.restore(notifyListeners: notifyListeners);
}
Expand Down
2 changes: 1 addition & 1 deletion lib/providers/home_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ class HomeProvider extends ChangeNotifier {
}
final settings = context.read<SettingsProvider>();

if (!settings.wakelockEnabled) {
if (!settings.kWakelock.value) {
WakelockPlus.disable();
} else {
switch (tab) {
Expand Down
11 changes: 6 additions & 5 deletions lib/providers/mobile_view_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class MobileViewProvider extends UnityProvider {
static Future<MobileViewProvider> ensureInitialized() async {
instance = MobileViewProvider._();
await instance.initialize();
debugPrint('MobileViewProvider initialized');
return instance;
}

Expand Down Expand Up @@ -73,7 +74,7 @@ class MobileViewProvider extends UnityProvider {
@override
Future<void> initialize() async {
await tryReadStorage(
() => super.initializeStorage(mobileView, kHiveMobileView));
() => super.initializeStorage(mobileView, kStorageMobileView));
for (final device in current) {
if (device != null) {
UnityPlayers.players[device.uuid] ??= UnityPlayers.forDevice(device);
Expand Down Expand Up @@ -190,8 +191,8 @@ class MobileViewProvider extends UnityProvider {
);
try {
await mobileView.write({
kHiveMobileView: jsonEncode(data),
kHiveMobileViewTab: tab,
kStorageMobileView: jsonEncode(data),
kStorageMobileViewTab: tab,
});
} catch (e) {
debugPrint(e.toString());
Expand All @@ -205,7 +206,7 @@ class MobileViewProvider extends UnityProvider {
Future<void> restore({bool notifyListeners = true}) async {
final data = await tryReadStorage(() => mobileView.read());
devices =
((await compute(jsonDecode, data[kHiveMobileView] as String)) as Map)
((await compute(jsonDecode, data[kStorageMobileView] as String)) as Map)
.map(
(key, value) => MapEntry<int, List<Device?>>(
int.parse(key),
Expand All @@ -225,7 +226,7 @@ class MobileViewProvider extends UnityProvider {
});
}

tab = data[kHiveMobileViewTab]!;
tab = data[kStorageMobileViewTab]!;
super.restore(notifyListeners: notifyListeners);
}
}
16 changes: 9 additions & 7 deletions lib/providers/server_provider.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class ServersProvider extends UnityProvider {
static Future<ServersProvider> ensureInitialized() async {
instance = ServersProvider._();
await instance.initialize();
debugPrint('ServersProvider initialized');
return instance;
}

Expand All @@ -55,7 +56,7 @@ class ServersProvider extends UnityProvider {
@override
Future<void> initialize() async {
await tryReadStorage(
() => super.initializeStorage(serversStorage, kHiveServers));
() => super.initializeStorage(serversStorage, kStorageServers));
refreshDevices(startup: true);
}

Expand All @@ -72,8 +73,9 @@ class ServersProvider extends UnityProvider {
// Register notification token.
try {
final data = await tryReadStorage(() => serversStorage.read());
final notificationToken = data[kHiveNotificationToken];
assert(notificationToken != null, '[kHiveNotificationToken] is null.');
final notificationToken = data[kStorageNotificationToken];
assert(
notificationToken != null, '[kStorageNotificationToken] is null.');
await API.instance
.registerNotificationToken(server, notificationToken!);
} catch (exception, stacktrace) {
Expand Down Expand Up @@ -183,7 +185,7 @@ class ServersProvider extends UnityProvider {
Future<void> save({bool notifyListeners = true}) async {
try {
await serversStorage.write({
kHiveServers: servers.map((e) => e.toJson()).toList(),
kStorageServers: servers.map((e) => e.toJson()).toList(),
});
} catch (e) {
debugPrint(e.toString());
Expand All @@ -196,9 +198,9 @@ class ServersProvider extends UnityProvider {
Future<void> restore({bool notifyListeners = true}) async {
final data = await tryReadStorage(() => serversStorage.read());

final serversData = data[kHiveServers] is String
? await compute(jsonDecode, data[kHiveServers] as String)
: data[kHiveServers] as List;
final serversData = data[kStorageServers] is String
? await compute(jsonDecode, data[kStorageServers] as String)
: data[kStorageServers] as List;
servers = serversData
.cast<Map<String, dynamic>>()
.map(Server.fromJson)
Expand Down
Loading
Loading