Skip to content
This repository has been archived by the owner on Jan 10, 2025. It is now read-only.

Commit

Permalink
Added video name and duration
Browse files Browse the repository at this point in the history
  • Loading branch information
ge59dil committed Jan 26, 2024
1 parent b2b1de2 commit 0b74950
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 25 deletions.
31 changes: 29 additions & 2 deletions lib/models/download/download_state_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,44 @@ import 'package:flutter/material.dart';

@immutable
class DownloadState {
final Map<int, String> downloadedVideos;
final Map<int, VideoDetails> downloadedVideos;

const DownloadState({
this.downloadedVideos = const {},
});

DownloadState copyWith({
Map<int, String>? downloadedVideos,
Map<int, VideoDetails>? downloadedVideos,
}) {
return DownloadState(
downloadedVideos: downloadedVideos ?? this.downloadedVideos,
);
}
}

@immutable
class VideoDetails {
final String filePath;
final String name;
final int duration; // Duration in seconds or your preferred unit

const VideoDetails({
required this.filePath,
required this.name,
required this.duration,
});

VideoDetails copyWith({
String? filePath,
String? name,
int? duration,
}) {
return VideoDetails(
filePath: filePath ?? this.filePath,
name: name ?? this.name,
duration: duration ?? this.duration,
);
}

// Implement toJson and fromJson if you need to serialize/deserialize the object
}
68 changes: 51 additions & 17 deletions lib/view_models/download_view_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,23 @@ class DownloadViewModel extends StateNotifier<DownloadState> {
final jsonString = prefs.getString('downloadedVideos');
if (jsonString != null) {
final downloaded = Map<String, dynamic>.from(json.decode(jsonString));
final downloadedVideos = downloaded
.map((key, value) => MapEntry(int.parse(key), value.toString()));
final downloadedVideos = downloaded.map((key, value) {
// Decode the JSON string into a Map
final videoDetailsMap = json.decode(value);
// Create a VideoDetails object from the Map
final videoDetails = VideoDetails(
filePath: videoDetailsMap['filePath'],
name: videoDetailsMap['name'],
duration: videoDetailsMap['duration'],
);
return MapEntry(int.parse(key), videoDetails);
}).cast<int, VideoDetails>(); // Ensure the map has the correct type
state = state.copyWith(downloadedVideos: downloadedVideos);
}
}

Future<String> downloadVideo(
String videoUrl, Int64 streamId, String fileName,) async {
String videoUrl, Int64 streamId, String fileName, String streamName, int streamDuration,) async {
try {
final directory = await getApplicationDocumentsDirectory();
final filePath = '${directory.path}/$fileName';
Expand All @@ -37,14 +46,38 @@ class DownloadViewModel extends StateNotifier<DownloadState> {

final prefs = await SharedPreferences.getInstance();
final int streamIdInt = streamId.toInt();
final downloadedVideos = Map<int, String>.from(state.downloadedVideos)
..[streamIdInt] = filePath;

// Save to SharedPreferences
// Create a map for the video details
final videoDetailsMap = {
'filePath': filePath,
'name': streamName,
'duration': streamDuration,
};

// 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;

await prefs.setString(
'downloadedVideos',
json.encode(downloadedVideos
.map((key, value) => MapEntry(key.toString(), value)),),);
'downloadedVideos',
json.encode(downloadedVideosJson.map((key, value) => MapEntry(key.toString(), value))),
);

// Convert the JSON strings back to VideoDetails objects for the state
final downloadedVideos = downloadedVideosJson.map((key, value) {
final videoDetailsMap = json.decode(value);
final videoDetails = VideoDetails(
filePath: videoDetailsMap['filePath'],
name: videoDetailsMap['name'],
duration: videoDetailsMap['duration'],
);
return MapEntry(key, videoDetails);
}).cast<int, VideoDetails>();

// Update the state
state = state.copyWith(downloadedVideos: downloadedVideos);
_logger.d('Downloaded videos: ${state.downloadedVideos}');
return filePath;
Expand All @@ -61,34 +94,35 @@ class DownloadViewModel extends StateNotifier<DownloadState> {
_logger.e('Error fetching downloaded videos: $e');
}
}

Future<void> deleteDownload(int videoId) async {
_logger.i('Deleting downloaded video with ID: $videoId');

try {
String? filePath = state.downloadedVideos[videoId];
if (filePath != null && filePath.isNotEmpty) {
// Get the VideoDetails object from the state
VideoDetails? videoDetails = state.downloadedVideos[videoId];
if (videoDetails != null) {
final filePath = videoDetails.filePath;
final file = File(filePath);
if (await file.exists()) {
await file.delete();
_logger.d('Deleted video file at: $filePath');

final prefs = await SharedPreferences.getInstance();
final updatedDownloads =
Map<int, String>.from(state.downloadedVideos);
final updatedDownloads = Map<int, VideoDetails>.from(state.downloadedVideos);
updatedDownloads.remove(videoId);

// Save updated list to SharedPreferences
// Convert VideoDetails objects to JSON strings before saving
await prefs.setString(
'downloadedVideos',
json.encode(updatedDownloads
.map((key, value) => MapEntry(key.toString(), value)),),);
json.encode(updatedDownloads.map((key, value) => MapEntry(key.toString(), json.encode(value))))
,);
state = state.copyWith(downloadedVideos: updatedDownloads);
} else {
_logger.w('File not found: $filePath');
}
} else {
_logger.w('No file path found for video ID: $videoId');
_logger.w('No details found for video ID: $videoId');
}
} catch (e) {
_logger.e('Error deleting video with ID $videoId: $e');
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:gocast_mobile/models/download/download_state_model.dart';
import 'package:gocast_mobile/providers.dart';
import 'package:gocast_mobile/views/components/custom_search_top_nav_bar.dart';
import 'package:gocast_mobile/views/course_view/downloaded_courses_view/download_card.dart';
Expand Down Expand Up @@ -42,14 +42,17 @@ class DownloadedCoursesState extends ConsumerState<DownloadedCourses> {
),
videoCards: downloadedVideos.entries.map((entry) {
final int videoId = entry.key;
final String localPath = entry.value;

final VideoDetails videoDetails = entry.value;
final String localPath = videoDetails.filePath;
final String videoName = videoDetails.name;
final int durationSeconds = videoDetails.duration;
final String formattedDuration = "${(durationSeconds ~/ 3600).toString().padLeft(2, '0')}:${((durationSeconds % 3600) ~/ 60).toString().padLeft(2, '0')}:${(durationSeconds % 60).toString().padLeft(2, '0')}";
return VideoCard(
duration:
"${Random().nextInt(2).toString().padLeft(2, '0')}:${Random().nextInt(59).toString().padLeft(2, '0')}:${Random().nextInt(60).toString().padLeft(2, '0')}",
formattedDuration,
imageName: 'assets/images/course1.png',
// Update as necessary
title: 'Video $videoId',
title: videoName,
// Replace with the appropriate title
date: 'Video Date',
// Replace with the appropriate date
Expand Down
2 changes: 1 addition & 1 deletion lib/views/video_view/video_player.dart
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ class VideoPlayerPageState extends ConsumerState<VideoPlayerPage> {
// Call the download function from the StreamViewModel
ref
.read(downloadViewModelProvider.notifier)
.downloadVideo(downloadUrl, stream.id, fileName)
.downloadVideo(downloadUrl, stream.id, fileName,stream.name,stream.duration)
.then((localPath) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Video Downloaded')),
Expand Down

0 comments on commit 0b74950

Please sign in to comment.