Skip to content

Commit

Permalink
fix downloading type error
Browse files Browse the repository at this point in the history
  • Loading branch information
GravityDarkLab committed Feb 3, 2024
1 parent 36fee62 commit d60d41a
Show file tree
Hide file tree
Showing 10 changed files with 149 additions and 86 deletions.
5 changes: 4 additions & 1 deletion lib/l10n/app_de.arb
Original file line number Diff line number Diff line change
Expand Up @@ -95,5 +95,8 @@
"enter_your_password": "Geben Sie Ihr Passwort ein",
"home": "Startseite",
"language_selection": "Sprache",
"language_selection_description": "Wählen Sie Ihre bevorzugte Sprache aus"
"language_selection_description": "Wählen Sie Ihre bevorzugte Sprache aus",
"download_completed": "Download abgeschlossen",
"download_failed": "Download fehlgeschlagen",
"download_canceled": "Download abgebrochen"
}
5 changes: 4 additions & 1 deletion lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -95,5 +95,8 @@
"enter_your_password": "Enter your password",
"home": "Home",
"language_selection": "Language",
"language_selection_description": "Select your preferred language"
"language_selection_description": "Select your preferred language",
"download_completed": "Download Completed",
"download_failed": "Download Failed",
"download_cancelled": "Download Cancelled"
}
5 changes: 4 additions & 1 deletion lib/l10n/app_es.arb
Original file line number Diff line number Diff line change
Expand Up @@ -95,5 +95,8 @@
"enter_your_password": "Introduce tu contraseña",
"home": "Inicio",
"language_selection": "Idioma",
"language_selection_description": "Selecciona tu idioma preferido."
"language_selection_description": "Selecciona tu idioma preferido.",
"download_complete": "Descarga completa",
"download_failed": "Error de descarga",
"download_cancelled": "Descarga cancelada"
}
5 changes: 4 additions & 1 deletion lib/l10n/app_fr.arb
Original file line number Diff line number Diff line change
Expand Up @@ -95,5 +95,8 @@
"enter_your_password": "Entrez votre mot de passe",
"home": "Accueil",
"language_selection": "Langue",
"language_selection_description": "Choisissez votre langue préférée."
"language_selection_description": "Choisissez votre langue préférée.",
"download_competed": "Téléchargement terminé",
"download_failed": "Échec du téléchargement",
"download_cancelled": "Téléchargement annulé"
}
23 changes: 20 additions & 3 deletions lib/models/download/download_state_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ class DownloadState {
});

DownloadState copyWith({
Map<int, VideoDetails>? downloadedVideos,
required Map<int, VideoDetails> downloadedVideos,
}) {
return DownloadState(
downloadedVideos: downloadedVideos ?? this.downloadedVideos,
downloadedVideos: downloadedVideos,
);
}
}
Expand All @@ -21,7 +21,7 @@ class DownloadState {
class VideoDetails {
final String filePath;
final String name;
final String duration; // Duration in seconds or your preferred unit
final String duration;
final String description;
final String date;

Expand All @@ -48,4 +48,21 @@ class VideoDetails {
date: date ?? this.date,
);
}

VideoDetails.fromJson(Map<String, dynamic> json)
: filePath = json['filePath'],
name = json['name'],
duration = json['duration'],
description = json['description'],
date = json['date'];

Map<String, dynamic> toJson() => {
'filePath': filePath,
'name': name,
'duration': duration,
'description': description,
'date': date,
};


}
1 change: 0 additions & 1 deletion lib/utils/tools.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import 'dart:ui';

import 'package:flutter/material.dart';

Expand Down
9 changes: 3 additions & 6 deletions lib/view_models/download_view_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,9 @@ class DownloadViewModel extends StateNotifier<DownloadState> {
'date': streamDate,
};

// Convert video details map to JSON string
final videoDetailsJson = json.encode(videoDetailsMap);

// Save the JSON string in your SharedPreferences
final downloadedVideosJson = Map<int, String>.from(state.downloadedVideos)
..[streamIdInt] = videoDetailsJson;
final downloadedVideosJson = Map<int, VideoDetails>.from(state.downloadedVideos)
..[streamIdInt] = VideoDetails.fromJson(videoDetailsMap);

await prefs.setString(
'downloadedVideos',
Expand All @@ -80,7 +77,7 @@ class DownloadViewModel extends StateNotifier<DownloadState> {

// Convert the JSON strings back to VideoDetails objects for the state
final downloadedVideos = downloadedVideosJson.map((key, value) {
final videoDetailsMap = json.decode(value);
final videoDetailsMap = value.toJson();
final videoDetails = VideoDetails(
filePath: videoDetailsMap['filePath'],
name: videoDetailsMap['name'],
Expand Down
4 changes: 2 additions & 2 deletions lib/views/course_view/components/small_stream_card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,9 @@ class SmallStreamCard extends StatelessWidget {
// Determine the URL based on the availability of roomNumber
final Uri url = roomNumber?.isNotEmpty ?? false
? Uri.parse(
'https://nav.tum.de/room/$roomNumber') // Use roomNumber in URL if available
'https://nav.tum.de/room/$roomNumber',) // Use roomNumber in URL if available
: Uri.parse(
'https://nav.tum.de/search?q=${Uri.encodeComponent(roomName ?? '')}'); // Fall back to search URL using roomName
'https://nav.tum.de/search?q=${Uri.encodeComponent(roomName ?? '')}',); // Fall back to search URL using roomName

return Align(
alignment: Alignment.centerRight,
Expand Down
87 changes: 87 additions & 0 deletions lib/views/video_view/utils/download_service.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:gocast_mobile/base/networking/api/gocast/api_v2.pb.dart';
import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:gocast_mobile/providers.dart';


class DownloadService {
final WidgetRef ref;
final bool Function() isWidgetMounted;
final Function(String message) onShowSnackBar;
final Function() showDownloadConfirmationDialog;
final Function() showMobileDataNotAllowedDialog;
final String startingDownloadMessage;
final String downloadNotAvailableMessage;
final String downloadCompletedMessage;
final String downloadFailedMessage;
final String donwloadCancelledMessage;



DownloadService({
required this.ref,
required this.isWidgetMounted,
required this.onShowSnackBar,
required this.startingDownloadMessage,
required this.downloadNotAvailableMessage,
required this.downloadCompletedMessage,
required this.downloadFailedMessage,
required this.donwloadCancelledMessage,
required this.showDownloadConfirmationDialog,
required this.showMobileDataNotAllowedDialog,
});

Future<void> downloadVideo(Stream stream, String type, String streamName, String streamDate) async {
bool canDownload = await _handleDownloadConnectivity(stream, type);
if (!canDownload) return;

String? downloadUrl;
for (var download in stream.downloads) {
if (download.friendlyName == type) {
downloadUrl = download.downloadURL;
break;
}
}

if (downloadUrl == null) {
if (!isWidgetMounted()) return;
onShowSnackBar(downloadNotAvailableMessage);
return;
}

onShowSnackBar(startingDownloadMessage);

ref.read(downloadViewModelProvider.notifier)
.downloadVideo(downloadUrl, stream, streamName, streamDate)
.then((localPath) {
if (!isWidgetMounted()) return;
onShowSnackBar(localPath.isNotEmpty ? downloadCompletedMessage : downloadFailedMessage);
});
}


Future<bool> _handleDownloadConnectivity(Stream stream, String type) async {
final isDownloadWithWifiOnly = ref
.watch(settingViewModelProvider)
.isDownloadWithWifiOnly;
var connectivityResult = await (Connectivity().checkConnectivity());
// If 'Download Over Wi-Fi Only' is enabled and connected to mobile, show a dialog
if (connectivityResult == ConnectivityResult.mobile && isDownloadWithWifiOnly) {
if (!isWidgetMounted()) return false;
showMobileDataNotAllowedDialog();
return false;
}
// If on mobile data and 'Download Over Wi-Fi Only' is disabled, ask for confirmation
if (connectivityResult == ConnectivityResult.mobile && !isDownloadWithWifiOnly) {
bool shouldProceed = await showDownloadConfirmationDialog();
if (!isWidgetMounted()) return false;
if (!shouldProceed) {
onShowSnackBar(donwloadCancelledMessage);
return false;
}
}
return true;
}


}
91 changes: 21 additions & 70 deletions lib/views/video_view/video_player.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import 'dart:async';

import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:gocast_mobile/base/networking/api/gocast/api_v2.pb.dart';
Expand All @@ -10,6 +9,7 @@ import 'package:gocast_mobile/views/chat_view/chat_view.dart';
import 'package:gocast_mobile/views/chat_view/inactive_view.dart';
import 'package:gocast_mobile/views/chat_view/poll_view.dart';
import 'package:gocast_mobile/views/video_view/utils/custom_video_control_bar.dart';
import 'package:gocast_mobile/views/video_view/utils/download_service.dart';
import 'package:gocast_mobile/views/video_view/utils/video_player_handler.dart';
import 'package:gocast_mobile/views/video_view/video_player_controller.dart';
import 'package:intl/intl.dart';
Expand Down Expand Up @@ -270,51 +270,28 @@ class VideoPlayerPageState extends ConsumerState<VideoPlayerPage> {
}

Future<void> _downloadVideo(Stream stream, String type) async {
// Extract the "Combined" download URL from the Stream object
bool canDownload = await _handleDownloadConnectivity(stream, type);
if (!canDownload) return; // Exit if download should not proceed

String? downloadUrl;
for (var download in stream.downloads) {
if (download.friendlyName == type) {
downloadUrl = download.downloadURL;
break;
}
}
if (downloadUrl == null) {
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(
'Download type "$type" not available for this lecture',),),
);
return;
}
// Use the extracted URL for downloading
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(AppLocalizations.of(context)!.starting_download)),
final downloadService = DownloadService(
ref: ref,
isWidgetMounted: () => mounted,
onShowSnackBar: (message) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(message)),
);
},
startingDownloadMessage: AppLocalizations.of(context)!.starting_download,
downloadNotAvailableMessage: AppLocalizations.of(context)!.download_not_allowed,
downloadCompletedMessage: AppLocalizations.of(context)!.download_completed,
downloadFailedMessage: AppLocalizations.of(context)!.download_failed,
donwloadCancelledMessage: AppLocalizations.of(context)!.download_cancelled,
showDownloadConfirmationDialog: _showDownloadConfirmationDialog,
showMobileDataNotAllowedDialog: _showMobileDataNotAllowedDialog,
);
// Call the download function from the StreamViewModel
String streamName = stream.name != '' ? stream.name : 'Lecture: ${DateFormat('EEEE. dd', Localizations.localeOf(context).toString()).format(stream.start.toDateTime())}';
String streamDate = DateFormat('dd MMMM yyyy', Localizations.localeOf(context).toString()).format(stream.start.toDateTime());
ref
.read(downloadViewModelProvider.notifier)
.downloadVideo(downloadUrl, stream, streamName, streamDate)
.then((localPath) {
if (localPath.isNotEmpty) {
// Download successful
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Video Downloaded')),
);
} else {
// Download failed, but not due to Wi-Fi (since it would throw an exception)
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Download failed')),
);
}
});
downloadService.downloadVideo(stream, type, streamName, streamDate);
}


Future<bool> _showDownloadConfirmationDialog() async {
return await showDialog(
context: context,
Expand Down Expand Up @@ -342,6 +319,8 @@ class VideoPlayerPageState extends ConsumerState<VideoPlayerPage> {
},
) ?? false; // If dialog is dismissed, return false
}


void _showMobileDataNotAllowedDialog() {
showDialog(
context: context,
Expand All @@ -363,34 +342,6 @@ class VideoPlayerPageState extends ConsumerState<VideoPlayerPage> {
},
);
}

Future<bool> _handleDownloadConnectivity(Stream stream, String type) async {
final isDownloadWithWifiOnly = ref
.watch(settingViewModelProvider)
.isDownloadWithWifiOnly;

var connectivityResult = await (Connectivity().checkConnectivity());

// If 'Download Over Wi-Fi Only' is enabled and connected to mobile, show a dialog
if (connectivityResult == ConnectivityResult.mobile && isDownloadWithWifiOnly) {
if (!mounted) return false;
_showMobileDataNotAllowedDialog();
return false;
}

// If on mobile data and 'Download Over Wi-Fi Only' is disabled, ask for confirmation
if (connectivityResult == ConnectivityResult.mobile && !isDownloadWithWifiOnly) {
bool shouldProceed = await _showDownloadConfirmationDialog();
if (!mounted) return false;
if (!shouldProceed) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Download cancelled')),
);
return false;
}
}

return true; // Proceed with download if all checks pass
}


}

0 comments on commit d60d41a

Please sign in to comment.