Skip to content

Commit 5d52e41

Browse files
author
code3-dev
committed
Add Download Options
1 parent 9e57545 commit 5d52e41

6 files changed

Lines changed: 293 additions & 19 deletions

File tree

app/build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ android {
1616
applicationId = "com.pira.ccloud"
1717
minSdk = 24
1818
targetSdk = 36
19-
versionCode = 4
20-
versionName = "1.0.3"
19+
versionCode = 5
20+
versionName = "1.0.4"
2121

2222
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
2323
}

app/src/main/java/com/pira/ccloud/VideoPlayerActivity.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ class VideoPlayerActivity : ComponentActivity() {
104104
// Enable immersive full-screen mode
105105
enableFullScreenMode()
106106

107+
// Keep screen on while in video player
108+
window.addFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
109+
107110
videoUrl = intent.getStringExtra(EXTRA_VIDEO_URL)
108111

109112
if (videoUrl != null) {
@@ -152,6 +155,9 @@ class VideoPlayerActivity : ComponentActivity() {
152155
// Ignore any exceptions during release
153156
}
154157
exoPlayer = null
158+
159+
// Remove keep screen on flag to conserve battery
160+
window.clearFlags(android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
155161
}
156162

157163
override fun onResume() {
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
package com.pira.ccloud.components
2+
3+
import androidx.compose.foundation.layout.Arrangement
4+
import androidx.compose.foundation.layout.Column
5+
import androidx.compose.foundation.layout.fillMaxWidth
6+
import androidx.compose.foundation.shape.RoundedCornerShape
7+
import androidx.compose.material3.AlertDialog
8+
import androidx.compose.material3.Button
9+
import androidx.compose.material3.MaterialTheme
10+
import androidx.compose.material3.Text
11+
import androidx.compose.material3.TextButton
12+
import androidx.compose.runtime.Composable
13+
import androidx.compose.ui.Modifier
14+
import androidx.compose.ui.unit.dp
15+
import com.pira.ccloud.data.model.Source
16+
17+
@Composable
18+
fun DownloadOptionsDialog(
19+
source: Source,
20+
onDismiss: () -> Unit,
21+
onCopyLink: () -> Unit,
22+
onDownloadWithBrowser: () -> Unit,
23+
onDownloadWithADM: () -> Unit,
24+
onOpenInVLC: () -> Unit
25+
) {
26+
AlertDialog(
27+
onDismissRequest = onDismiss,
28+
title = {
29+
Text(
30+
text = "Download Options",
31+
style = MaterialTheme.typography.headlineSmall,
32+
fontWeight = androidx.compose.ui.text.font.FontWeight.Bold
33+
)
34+
},
35+
text = {
36+
Text(
37+
text = "Choose how to download this video",
38+
style = MaterialTheme.typography.bodyMedium,
39+
color = MaterialTheme.colorScheme.onSurfaceVariant
40+
)
41+
},
42+
confirmButton = {
43+
Column(
44+
modifier = Modifier.fillMaxWidth(),
45+
verticalArrangement = Arrangement.spacedBy(8.dp)
46+
) {
47+
Button(
48+
onClick = {
49+
onCopyLink()
50+
onDismiss()
51+
},
52+
modifier = Modifier.fillMaxWidth(),
53+
shape = RoundedCornerShape(16.dp),
54+
colors = androidx.compose.material3.ButtonDefaults.buttonColors(
55+
containerColor = MaterialTheme.colorScheme.primaryContainer,
56+
contentColor = MaterialTheme.colorScheme.onPrimaryContainer
57+
)
58+
) {
59+
Text("Copy Link")
60+
}
61+
62+
Button(
63+
onClick = {
64+
onDownloadWithBrowser()
65+
onDismiss()
66+
},
67+
modifier = Modifier.fillMaxWidth(),
68+
shape = RoundedCornerShape(16.dp),
69+
colors = androidx.compose.material3.ButtonDefaults.buttonColors(
70+
containerColor = MaterialTheme.colorScheme.primaryContainer,
71+
contentColor = MaterialTheme.colorScheme.onPrimaryContainer
72+
)
73+
) {
74+
Text("Download with Browser")
75+
}
76+
77+
Button(
78+
onClick = {
79+
onDownloadWithADM()
80+
onDismiss()
81+
},
82+
modifier = Modifier.fillMaxWidth(),
83+
shape = RoundedCornerShape(16.dp),
84+
colors = androidx.compose.material3.ButtonDefaults.buttonColors(
85+
containerColor = MaterialTheme.colorScheme.primaryContainer,
86+
contentColor = MaterialTheme.colorScheme.onPrimaryContainer
87+
)
88+
) {
89+
Text("Download with ADM")
90+
}
91+
92+
Button(
93+
onClick = {
94+
onOpenInVLC()
95+
onDismiss()
96+
},
97+
modifier = Modifier.fillMaxWidth(),
98+
shape = RoundedCornerShape(16.dp),
99+
colors = androidx.compose.material3.ButtonDefaults.buttonColors(
100+
containerColor = MaterialTheme.colorScheme.primaryContainer,
101+
contentColor = MaterialTheme.colorScheme.onPrimaryContainer
102+
)
103+
) {
104+
Text("Open in VLC Player")
105+
}
106+
107+
TextButton(
108+
onClick = onDismiss,
109+
modifier = Modifier.fillMaxWidth()
110+
) {
111+
Text("Cancel")
112+
}
113+
}
114+
},
115+
containerColor = MaterialTheme.colorScheme.surface,
116+
shape = RoundedCornerShape(20.dp),
117+
tonalElevation = 6.dp
118+
)
119+
}

app/src/main/java/com/pira/ccloud/screens/SingleMovieScreen.kt

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,10 @@ import androidx.navigation.NavController
6060
import coil.compose.rememberAsyncImagePainter
6161
import coil.request.ImageRequest
6262
import com.pira.ccloud.VideoPlayerActivity
63+
import com.pira.ccloud.components.DownloadOptionsDialog
6364
import com.pira.ccloud.data.model.Movie
6465
import com.pira.ccloud.data.model.Source
66+
import com.pira.ccloud.utils.DownloadUtils
6567
import com.pira.ccloud.utils.StorageUtils
6668

6769
@OptIn(ExperimentalMaterial3Api::class)
@@ -390,6 +392,20 @@ fun SourceOptionsDialog(
390392
onDownload: (Source) -> Unit,
391393
onPlay: (Source) -> Unit
392394
) {
395+
val context = LocalContext.current
396+
var showDownloadOptions by remember { mutableStateOf(false) }
397+
398+
if (showDownloadOptions) {
399+
DownloadOptionsDialog(
400+
source = source,
401+
onDismiss = { showDownloadOptions = false },
402+
onCopyLink = { DownloadUtils.copyToClipboard(context, source.url) },
403+
onDownloadWithBrowser = { DownloadUtils.openUrl(context, source.url) },
404+
onDownloadWithADM = { DownloadUtils.openWithADM(context, source.url) },
405+
onOpenInVLC = { DownloadUtils.openWithVLC(context, source.url) }
406+
)
407+
}
408+
393409
AlertDialog(
394410
onDismissRequest = onDismiss,
395411
title = {
@@ -412,7 +428,7 @@ fun SourceOptionsDialog(
412428
verticalArrangement = Arrangement.spacedBy(12.dp)
413429
) {
414430
Button(
415-
onClick = { onDownload(source) },
431+
onClick = { showDownloadOptions = true },
416432
modifier = Modifier.fillMaxWidth(),
417433
shape = RoundedCornerShape(16.dp),
418434
elevation = androidx.compose.material3.ButtonDefaults.elevatedButtonElevation()
@@ -423,7 +439,7 @@ fun SourceOptionsDialog(
423439
modifier = Modifier.size(20.dp)
424440
)
425441
Spacer(modifier = Modifier.width(8.dp))
426-
Text("Download in Browser")
442+
Text("Download Options")
427443
}
428444

429445
Button(
@@ -461,11 +477,8 @@ fun SourceOptionsDialog(
461477
)
462478
}
463479

480+
464481
fun openUrl(context: Context, url: String) {
465-
try {
466-
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
467-
context.startActivity(intent)
468-
} catch (e: Exception) {
469-
// Handle error or show a message
470-
}
471-
}
482+
DownloadUtils.openUrl(context, url)
483+
}
484+

app/src/main/java/com/pira/ccloud/screens/SingleSeriesScreen.kt

Lines changed: 62 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,12 @@ import androidx.navigation.NavController
6161
import coil.compose.rememberAsyncImagePainter
6262
import coil.request.ImageRequest
6363
import com.pira.ccloud.VideoPlayerActivity
64+
import com.pira.ccloud.components.DownloadOptionsDialog
6465
import com.pira.ccloud.data.model.Episode
6566
import com.pira.ccloud.data.model.Series
6667
import com.pira.ccloud.data.model.Source
6768
import com.pira.ccloud.ui.series.SeasonsViewModel
69+
import com.pira.ccloud.utils.DownloadUtils
6870
import com.pira.ccloud.utils.StorageUtils
6971

7072
@OptIn(ExperimentalMaterial3Api::class)
@@ -181,6 +183,21 @@ fun SourceOptionsDialog(
181183
onDownload: (Source) -> Unit,
182184
onPlay: (Source) -> Unit
183185
) {
186+
val context = LocalContext.current
187+
var selectedSource by remember { mutableStateOf<Source?>(null) }
188+
var showDownloadOptions by remember { mutableStateOf(false) }
189+
190+
if (showDownloadOptions && selectedSource != null) {
191+
DownloadOptionsDialog(
192+
source = selectedSource!!,
193+
onDismiss = { showDownloadOptions = false },
194+
onCopyLink = { DownloadUtils.copyToClipboard(context, selectedSource!!.url) },
195+
onDownloadWithBrowser = { DownloadUtils.openUrl(context, selectedSource!!.url) },
196+
onDownloadWithADM = { DownloadUtils.openWithADM(context, selectedSource!!.url) },
197+
onOpenInVLC = { DownloadUtils.openWithVLC(context, selectedSource!!.url) }
198+
)
199+
}
200+
184201
AlertDialog(
185202
onDismissRequest = onDismiss,
186203
title = {
@@ -202,6 +219,28 @@ fun SourceOptionsDialog(
202219
modifier = Modifier.fillMaxWidth(),
203220
verticalArrangement = Arrangement.spacedBy(12.dp)
204221
) {
222+
// Download options button
223+
Button(
224+
onClick = {
225+
if (episode.sources.size == 1) {
226+
selectedSource = episode.sources[0]
227+
showDownloadOptions = true
228+
}
229+
},
230+
enabled = episode.sources.isNotEmpty(),
231+
modifier = Modifier.fillMaxWidth(),
232+
shape = RoundedCornerShape(16.dp),
233+
elevation = androidx.compose.material3.ButtonDefaults.elevatedButtonElevation()
234+
) {
235+
Icon(
236+
imageVector = Icons.Default.Download,
237+
contentDescription = "Download",
238+
modifier = Modifier.size(20.dp)
239+
)
240+
Spacer(modifier = Modifier.width(8.dp))
241+
Text("Download Options")
242+
}
243+
205244
// Play buttons for each source/quality
206245
episode.sources.forEach { source ->
207246
Button(
@@ -242,6 +281,21 @@ fun DownloadMenu(
242281
onDismiss: () -> Unit,
243282
onDownload: (Source) -> Unit
244283
) {
284+
val context = LocalContext.current
285+
var selectedSource by remember { mutableStateOf<Source?>(null) }
286+
var showDownloadOptions by remember { mutableStateOf(false) }
287+
288+
if (showDownloadOptions && selectedSource != null) {
289+
DownloadOptionsDialog(
290+
source = selectedSource!!,
291+
onDismiss = { showDownloadOptions = false },
292+
onCopyLink = { DownloadUtils.copyToClipboard(context, selectedSource!!.url) },
293+
onDownloadWithBrowser = { DownloadUtils.openUrl(context, selectedSource!!.url) },
294+
onDownloadWithADM = { DownloadUtils.openWithADM(context, selectedSource!!.url) },
295+
onOpenInVLC = { DownloadUtils.openWithVLC(context, selectedSource!!.url) }
296+
)
297+
}
298+
245299
AlertDialog(
246300
onDismissRequest = onDismiss,
247301
title = {
@@ -265,7 +319,10 @@ fun DownloadMenu(
265319
) {
266320
sources.forEach { source ->
267321
Button(
268-
onClick = { onDownload(source) },
322+
onClick = {
323+
selectedSource = source
324+
showDownloadOptions = true
325+
},
269326
modifier = Modifier.fillMaxWidth(),
270327
shape = RoundedCornerShape(16.dp),
271328
colors = androidx.compose.material3.ButtonDefaults.buttonColors(
@@ -300,6 +357,7 @@ fun DownloadMenu(
300357
)
301358
}
302359

360+
303361
@Composable
304362
fun SeriesDetailsContent(
305363
series: Series,
@@ -744,10 +802,6 @@ fun EpisodeItem(
744802
}
745803

746804
fun openUrlSeries(context: Context, url: String) {
747-
try {
748-
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
749-
context.startActivity(intent)
750-
} catch (e: Exception) {
751-
// Handle error or show a message
752-
}
753-
}
805+
DownloadUtils.openUrl(context, url)
806+
}
807+

0 commit comments

Comments
 (0)