From 6468fe963749017c3b78cad52c502b51e3d17c6f Mon Sep 17 00:00:00 2001 From: Prateek Sunal Date: Tue, 28 Jan 2025 16:56:17 +0530 Subject: [PATCH] feat: add video streaming setting --- .../lib/events/video_streaming_changed.dart | 5 +++ mobile/lib/main.dart | 2 +- mobile/lib/services/preview_video_store.dart | 35 +++++++++++++++++-- .../services/user_remote_flag_service.dart | 1 + .../ui/settings/advanced_settings_screen.dart | 23 ++++++++++++ 5 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 mobile/lib/events/video_streaming_changed.dart diff --git a/mobile/lib/events/video_streaming_changed.dart b/mobile/lib/events/video_streaming_changed.dart new file mode 100644 index 0000000000..23d90b08b3 --- /dev/null +++ b/mobile/lib/events/video_streaming_changed.dart @@ -0,0 +1,5 @@ +import "package:photos/events/event.dart"; + +// todo: consider removing this once we opt for riverpod or similar state management +// solution +class VideoStreamingChanged extends Event {} diff --git a/mobile/lib/main.dart b/mobile/lib/main.dart index e4b2c37142..70deb70cd7 100644 --- a/mobile/lib/main.dart +++ b/mobile/lib/main.dart @@ -286,7 +286,7 @@ Future _init(bool isBackground, {String via = ''}) async { }); } _logger.info("PushService/HomeWidget done $tlog"); - PreviewVideoStore.instance.init(); + PreviewVideoStore.instance.init(preferences); unawaited(SemanticSearchService.instance.init()); unawaited(MLService.instance.init()); await PersonService.init( diff --git a/mobile/lib/services/preview_video_store.dart b/mobile/lib/services/preview_video_store.dart index 6b5e1dd81e..f9071bee49 100644 --- a/mobile/lib/services/preview_video_store.dart +++ b/mobile/lib/services/preview_video_store.dart @@ -13,16 +13,18 @@ import "package:logging/logging.dart"; import "package:path_provider/path_provider.dart"; import "package:photos/core/cache/video_cache_manager.dart"; import "package:photos/core/configuration.dart"; +import "package:photos/core/event_bus.dart"; import "package:photos/core/network/network.dart"; +import "package:photos/events/video_streaming_changed.dart"; import "package:photos/models/base/id.dart"; import "package:photos/models/file/file.dart"; import "package:photos/models/file/file_type.dart"; -import "package:photos/service_locator.dart"; import "package:photos/services/filedata/filedata_service.dart"; import "package:photos/utils/file_key.dart"; import "package:photos/utils/file_util.dart"; import "package:photos/utils/gzip.dart"; import "package:photos/utils/toast_util.dart"; +import "package:shared_preferences/shared_preferences.dart"; class PreviewVideoStore { PreviewVideoStore._privateConstructor(); @@ -38,10 +40,37 @@ class PreviewVideoStore { bool isUploading = false; final _dio = NetworkClient.instance.enteDio; - void init() {} + + void init(SharedPreferences prefs) { + _prefs = prefs; + } + + late final SharedPreferences _prefs; + static const String _videoStreamingEnabled = "videoStreamingEnabled"; + static const String _videoStreamingCutoff = "videoStreamingCutoff"; + + bool get isVideoStreamingEnabled { + return _prefs.getBool(_videoStreamingEnabled) ?? true; + } + + Future setIsVideoStreamingEnabled(bool value) async { + final oneMonthBack = DateTime.now().subtract(const Duration(days: 30)); + await _prefs.setBool(_videoStreamingEnabled, value); + await _prefs.setInt( + _videoStreamingCutoff, + oneMonthBack.millisecondsSinceEpoch, + ); + Bus.instance.fire(VideoStreamingChanged()); + } + + Future get videoStreamingCutoff async { + final milliseconds = _prefs.getInt(_videoStreamingCutoff); + if (milliseconds == null) return null; + return DateTime.fromMillisecondsSinceEpoch(milliseconds); + } Future chunkAndUploadVideo(BuildContext? ctx, EnteFile enteFile) async { - if (!enteFile.isUploaded || !flagService.internalUser) return; + if (!enteFile.isUploaded || !isVideoStreamingEnabled) return; final file = await getFile(enteFile, isOrigin: true); if (file == null) return; try { diff --git a/mobile/lib/services/user_remote_flag_service.dart b/mobile/lib/services/user_remote_flag_service.dart index 7a49b38d53..42bc45a60d 100644 --- a/mobile/lib/services/user_remote_flag_service.dart +++ b/mobile/lib/services/user_remote_flag_service.dart @@ -19,6 +19,7 @@ class UserRemoteFlagService { static const String recoveryVerificationFlag = "recoveryKeyVerified"; static const String mapEnabled = "mapEnabled"; static const String mlEnabled = "faceSearchEnabled"; + static const String videoStreamingEnabled = "videoStreamingEnabled"; static const String needRecoveryKeyVerification = "needRecoveryKeyVerification"; diff --git a/mobile/lib/ui/settings/advanced_settings_screen.dart b/mobile/lib/ui/settings/advanced_settings_screen.dart index 7df16fd8bf..7969980cbf 100644 --- a/mobile/lib/ui/settings/advanced_settings_screen.dart +++ b/mobile/lib/ui/settings/advanced_settings_screen.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import "package:photos/core/error-reporting/super_logging.dart"; import "package:photos/generated/l10n.dart"; import "package:photos/service_locator.dart"; +import "package:photos/services/preview_video_store.dart"; import "package:photos/services/user_remote_flag_service.dart"; import 'package:photos/theme/ente_theme.dart'; import 'package:photos/ui/components/buttons/icon_button_widget.dart'; @@ -116,6 +117,28 @@ class AdvancedSettingsScreen extends StatelessWidget { }, ), ), + if (flagService.internalUser) ...[ + const SizedBox(height: 24), + MenuItemWidget( + captionedTextWidget: CaptionedTextWidget( + title: S.of(context).videoStreaming, + ), + menuItemColor: colorScheme.fillFaint, + singleBorderRadius: 8, + alignCaptionedTextToLeft: true, + trailingWidget: ToggleSwitchWidget( + value: () => PreviewVideoStore + .instance.isVideoStreamingEnabled, + onChanged: () async { + final isEnabled = PreviewVideoStore + .instance.isVideoStreamingEnabled; + + await PreviewVideoStore.instance + .setIsVideoStreamingEnabled(!isEnabled); + }, + ), + ), + ], const SizedBox( height: 24, ),