update
This commit is contained in:
@@ -15,6 +15,9 @@ interface VideoApi {
|
|||||||
@POST("videos/{id}/download")
|
@POST("videos/{id}/download")
|
||||||
suspend fun triggerDownload(@Path("id") id: Int): Map<String, String>
|
suspend fun triggerDownload(@Path("id") id: Int): Map<String, String>
|
||||||
|
|
||||||
|
@retrofit2.http.DELETE("videos")
|
||||||
|
suspend fun deleteNotDownloaded(@Query("profile_id") profileId: Int): Map<String, Int>
|
||||||
|
|
||||||
@GET("profiles")
|
@GET("profiles")
|
||||||
suspend fun getProfiles(): List<Profile>
|
suspend fun getProfiles(): List<Profile>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,11 @@ class VideoRepository(private val api: VideoApi = ApiClient.api) {
|
|||||||
response["status"] ?: "unknown"
|
response["status"] ?: "unknown"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun deleteNotDownloaded(profileId: Int): Result<Int> = runCatching {
|
||||||
|
val response = api.deleteNotDownloaded(profileId)
|
||||||
|
response["deleted"] ?: 0
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun getProfiles(): Result<List<Profile>> = runCatching { api.getProfiles() }
|
suspend fun getProfiles(): Result<List<Profile>> = runCatching { api.getProfiles() }
|
||||||
|
|
||||||
fun getStreamUrl(videoId: Int): String = "${ApiClient.BASE_URL}videos/$videoId/stream"
|
fun getStreamUrl(videoId: Int): String = "${ApiClient.BASE_URL}videos/$videoId/stream"
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.youtubeapp.ui.navigation
|
|||||||
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.DeleteSweep
|
||||||
import androidx.compose.material.icons.filled.Download
|
import androidx.compose.material.icons.filled.Download
|
||||||
import androidx.compose.material.icons.filled.Person
|
import androidx.compose.material.icons.filled.Person
|
||||||
import androidx.compose.material.icons.filled.VideoLibrary
|
import androidx.compose.material.icons.filled.VideoLibrary
|
||||||
@@ -64,6 +65,9 @@ fun AppNavigation() {
|
|||||||
TopAppBar(
|
TopAppBar(
|
||||||
title = { Text("YouTube App") },
|
title = { Text("YouTube App") },
|
||||||
actions = {
|
actions = {
|
||||||
|
IconButton(onClick = { viewModel.deleteNotDownloaded() }) {
|
||||||
|
Icon(Icons.Default.DeleteSweep, contentDescription = "Aufraeumen")
|
||||||
|
}
|
||||||
IconButton(onClick = { showProfileMenu = true }) {
|
IconButton(onClick = { showProfileMenu = true }) {
|
||||||
Icon(Icons.Default.Person, contentDescription = "Profil")
|
Icon(Icons.Default.Person, contentDescription = "Profil")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -126,6 +126,14 @@ class VideoViewModel : ViewModel() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun deleteNotDownloaded() {
|
||||||
|
val profileId = _state.value.selectedProfileId ?: return
|
||||||
|
viewModelScope.launch {
|
||||||
|
repository.deleteNotDownloaded(profileId)
|
||||||
|
loadAllVideos()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun deleteLocalVideo(videoId: Int) {
|
fun deleteLocalVideo(videoId: Int) {
|
||||||
localStorage?.deleteLocalFile(videoId)
|
localStorage?.deleteLocalFile(videoId)
|
||||||
_state.value = _state.value.copy(downloadStatus = "Lokal gelöscht")
|
_state.value = _state.value.copy(downloadStatus = "Lokal gelöscht")
|
||||||
|
|||||||
Binary file not shown.
@@ -39,6 +39,12 @@ def get_downloaded_videos(profile_id: Optional[int] = Query(None), db: Session =
|
|||||||
return [VideoResponse.from_model(v) for v in videos]
|
return [VideoResponse.from_model(v) for v in videos]
|
||||||
|
|
||||||
|
|
||||||
|
@router.delete("")
|
||||||
|
def delete_not_downloaded(profile_id: int = Query(...), db: Session = Depends(get_db)):
|
||||||
|
count = video_service.delete_not_downloaded(db, profile_id)
|
||||||
|
return {"deleted": count}
|
||||||
|
|
||||||
|
|
||||||
@router.post("/{video_id}/download")
|
@router.post("/{video_id}/download")
|
||||||
def trigger_download(video_id: int, db: Session = Depends(get_db)):
|
def trigger_download(video_id: int, db: Session = Depends(get_db)):
|
||||||
video = video_service.get_video(db, video_id)
|
video = video_service.get_video(db, video_id)
|
||||||
|
|||||||
Binary file not shown.
@@ -48,5 +48,17 @@ def update_file_path(db: Session, video_id: int, path: str):
|
|||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
|
|
||||||
|
def delete_not_downloaded(db: Session, profile_id: int) -> int:
|
||||||
|
videos = db.query(Video).filter(
|
||||||
|
Video.file_path.is_(None),
|
||||||
|
Video.profiles.any(Profile.id == profile_id),
|
||||||
|
).all()
|
||||||
|
count = len(videos)
|
||||||
|
for video in videos:
|
||||||
|
db.delete(video)
|
||||||
|
db.commit()
|
||||||
|
return count
|
||||||
|
|
||||||
|
|
||||||
def get_all_profiles(db: Session) -> list[Profile]:
|
def get_all_profiles(db: Session) -> list[Profile]:
|
||||||
return db.query(Profile).all()
|
return db.query(Profile).all()
|
||||||
|
|||||||
@@ -12,3 +12,4 @@
|
|||||||
- Klick auf Download lädt das Video herunter und wird lokal auf dem Client gespeichert
|
- Klick auf Download lädt das Video herunter und wird lokal auf dem Client gespeichert
|
||||||
- Klick auf Icon zeigt verfügbare Profile
|
- Klick auf Icon zeigt verfügbare Profile
|
||||||
- Das ausgewählte Profil wird persistiert und bestimmt welche Videos angezeigt werden
|
- Das ausgewählte Profil wird persistiert und bestimmt welche Videos angezeigt werden
|
||||||
|
- Klick auf Icon löscht alle nicht heruntergeladenen Videos vom aktuellen Profil
|
||||||
Reference in New Issue
Block a user