Skip to content

Commit

Permalink
- Added User Preferences & other UX Improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
AkshathSai committed Jun 26, 2024
1 parent b1c2e7f commit ba96490
Show file tree
Hide file tree
Showing 13 changed files with 171 additions and 59 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.3</version>
<version>3.3.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.akshathsaipittala</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.Accessors;
import org.springframework.content.commons.annotations.ContentId;
import org.springframework.content.commons.annotations.ContentLength;
import org.springframework.content.commons.annotations.MimeType;
Expand All @@ -17,6 +18,7 @@
@Entity
@Getter
@Setter
@Accessors(chain = true)
@NoArgsConstructor
public class Movie implements Serializable {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.akshathsaipittala.streamspace.entity;

import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.Accessors;

@Entity
@Getter
@Setter
@Accessors(chain = true)
@NoArgsConstructor
public class Preference {

@Id
private Integer prefId;
private String name;
private boolean enabled;
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,22 +50,24 @@ public void indexMovie(TorrentFile file, String torrentName, String fileName, To
if (movie != null) {
log.info("Movie Found {}", movie);
movieRepository.delete(movie);
// Primary key cannot be updated due to which new record is created need to revisit
// TODO: need to revisit
// Primary key cannot be updated due to which new record is created
// hence deleting and inserting as new with latest torrentId
movie.setMovieCode(torrentId.toString().toUpperCase());
log.info("{} already indexed", fileName);
movieRepository.save(movie);
} else {
movie = new Movie();
movie.setContentLength(file.getSize());
movie.setName(fileName);
movie.setSummary(fileName);
movie.setContentMimeType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
log.info(runtimeHelper.getMoviesContentStore() + torrentName + "/" + fileName);
movie.setContentId(runtimeHelper.getMoviesContentStore() + torrentName + "/" + fileName);
movie.setMovieCode(torrentId.toString().toUpperCase());
movie.setMediaSource(ApplicationConstants.TORRENT);
movie = new Movie()
.setContentLength(file.getSize())
.setName(fileName)
.setSummary(fileName)
.setContentMimeType(MediaType.APPLICATION_OCTET_STREAM_VALUE)
.setContentId(runtimeHelper.getMoviesContentStore() + torrentName + "/" + fileName)
.setMovieCode(torrentId.toString().toUpperCase())
.setMediaSource(ApplicationConstants.TORRENT);

log.info("Content ID {}", runtimeHelper.getMoviesContentStore() + torrentName + "/" + fileName);
movieRepository.save(movie);
log.info("{}", movie);
}

}
Expand All @@ -84,7 +86,6 @@ public void indexMusic(TorrentFile file, String torrentName, String fileName, To
song.setSongId(torrentId.toString().toUpperCase());
song.setMediaSource(ApplicationConstants.TORRENT);
musicRepository.save(song);
log.info("{}", song);
}

/**
Expand Down Expand Up @@ -198,14 +199,15 @@ private List<Movie> createMovieEntities(List<Path> paths) throws IOException {
log.debug("Content Store {}", contentStoreDir);
log.debug("Local Directory {}", userDir);

Movie movie = new Movie();
movie.setName(encodedFileName);
movie.setContentLength(Files.size(entry));
movie.setSummary(entry.getFileName().toString());
movie.setContentId(decodePathSegment.apply(contentStoreDir));
movie.setContentMimeType(decodeContentType.apply(entry));
movie.setMovieCode(HelperFunctions.generateUniqueCode());
movie.setMediaSource(ApplicationConstants.LOCAL_MEDIA);
Movie movie = new Movie()
.setName(encodedFileName)
.setContentLength(Files.size(entry))
.setSummary(entry.getFileName().toString())
.setContentId(decodePathSegment.apply(contentStoreDir))
.setContentMimeType(decodeContentType.apply(entry))
.setMovieCode(HelperFunctions.generateUniqueCode())
.setMediaSource(ApplicationConstants.LOCAL_MEDIA);

moviesList.add(movie);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.akshathsaipittala.streamspace.repository;

import com.akshathsaipittala.streamspace.entity.Preference;
import org.springframework.data.repository.ListCrudRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface UserPreferences extends ListCrudRepository<Preference, Integer> {

}

Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package com.akshathsaipittala.streamspace.services;

import com.akshathsaipittala.streamspace.entity.CONTENTTYPE;
import com.akshathsaipittala.streamspace.entity.DownloadTask;
import com.akshathsaipittala.streamspace.entity.STATUS;
import com.akshathsaipittala.streamspace.entity.DownloadTaskSpecs;
import com.akshathsaipittala.streamspace.entity.*;
import com.akshathsaipittala.streamspace.indexer.MediaIndexer;
import com.akshathsaipittala.streamspace.repository.DownloadTaskRepository;
import com.akshathsaipittala.streamspace.repository.UserPreferences;
import com.akshathsaipittala.streamspace.utils.RuntimeHelper;
import jakarta.annotation.PreDestroy;
import lombok.extern.slf4j.Slf4j;
Expand Down Expand Up @@ -41,12 +39,20 @@ public class BackgroundServices {
@Autowired
private TorrentDownloadService torrentDownloadService;

@Lazy
@Autowired
private UserPreferences userPreferences;

@Async
@EventListener(ApplicationReadyEvent.class)
public void onApplicationReadyEvent() {
try {
log.info("Indexing Local Media");
// Runs only during initial setup
if (userPreferences.count() == 0) {
configurePreferences();
}

mediaIndexer.indexLocalMedia(
runtimeHelper.getMediaFolders().get(CONTENTTYPE.VIDEO),
runtimeHelper.getMediaFolders().get(CONTENTTYPE.AUDIO)
Expand All @@ -60,6 +66,13 @@ public void onApplicationReadyEvent() {
}
}

private void configurePreferences() {
List<Preference> features = List.of(
new Preference().setPrefId(1).setName("DARK_MODE_ENABLED")
);
userPreferences.saveAll(features);
}

@Async
public void startBackgroundDownloads() {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.akshathsaipittala.streamspace.web.api;

import com.akshathsaipittala.streamspace.entity.Preference;
import com.akshathsaipittala.streamspace.repository.UserPreferences;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Optional;

@Slf4j
@RestController
@RequestMapping("/preference")
@RequiredArgsConstructor
public class PreferencesAPI {

final UserPreferences userPreferences;

@PatchMapping
public ResponseEntity<Void> saveDarkModePreference(@RequestBody Preference preference) {
Optional<Preference> existingPref = userPreferences.findById(preference.getPrefId());
if (existingPref.isPresent()) {
Preference updatedPref = existingPref.get();
updatedPref.setEnabled(preference.isEnabled());
userPreferences.save(updatedPref);
} else {
//userPreferences.save(preference);
log.info("Preference with id {} not found", preference.getPrefId());
}
return ResponseEntity.ok().build();
}

}
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
package com.akshathsaipittala.streamspace.web.controllers;

import com.akshathsaipittala.streamspace.entity.Preference;
import com.akshathsaipittala.streamspace.repository.UserPreferences;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.Optional;

@Controller
@RequiredArgsConstructor
public class WebController {

final UserPreferences userPreferences;

@GetMapping("/")
public String index() {
public String index(Model model) {
Optional<Preference> darkModePreference = userPreferences.findById(1);
boolean darkModeEnabled = darkModePreference.map(Preference::isEnabled).orElse(false);
model.addAttribute("darkmodeenabled", darkModeEnabled);
return "index";
}

Expand Down
4 changes: 2 additions & 2 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ management.endpoints.web.exposure.include=health,metrics
#server.ssl.bundle=web-server
#server.ssl.client-auth=none

spring.datasource.url=jdbc:h2:file:~/.h2
#spring.datasource.url=jdbc:h2:mem:db
#spring.datasource.url=jdbc:h2:file:~/.h2
spring.datasource.url=jdbc:h2:mem:db
spring.datasource.username=sa
spring.datasource.password=password
spring.datasource.driver-class-name=org.h2.Driver
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/templates/downloads.html
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ <h3 class="display-6 pt-3">Torrents Web Downloader

<div th:each="task : ${tasks}">

<!--TODO: Allow User to cancel a download-->
<!--<div class="pb-3 text-end">
<a hx-post="/download/togglePause" class="btn btn-warning btn-sm">Pause All Downloads</a>
</div>-->
Expand Down
37 changes: 20 additions & 17 deletions src/main/resources/templates/index.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
lang="en">
lang="en"
th:attrappend="data-bs-theme=${darkmodeenabled ? 'dark' : ''}">
<head>
<meta charset="UTF-8">
<title>Stream Space</title>
Expand Down Expand Up @@ -169,8 +170,7 @@
}
.dark {
background-color: black;
color: white;

/*color: white;*/
}

/* YT TRAILER MODAL-------------------------------------------------- */
Expand Down Expand Up @@ -288,8 +288,7 @@
</head>

<!--<body data-bs-theme="dark" class="dark">-->
<body>

<body th:styleappend="${darkmodeenabled}? 'background-color: black;' : ''">
<div id="globalProgress" class="globalProgress" style="height: 3px; background-color: white;">
<div class="indeterminate" style="background-color: red;"></div>
</div>
Expand All @@ -316,7 +315,7 @@
<span class="input-group-text" id="btnSwitch">
<!-- <i class="bi bi-shadows"></i>-->
<i class="bi bi-search"></i>&nbsp;&nbsp;
<i class="bi bi-moon-stars-fill"></i>
<i class="bi bi-moon-stars-fill" data-toggle="tooltip" title="Toggle Dark Mode"></i>
</span>
</div>

Expand Down Expand Up @@ -627,17 +626,21 @@ <h1 class="display-6">Download Queue</h1>
<!--<script th:src="@{/webjars/bootstrap/js/bootstrap.min.js}"></script>-->
<script th:src="@{/webjars/htmx.org/dist/ext/ws.js}"></script>
<script>
document.getElementById('btnSwitch').addEventListener('click',()=>{
if (document.documentElement.getAttribute('data-bs-theme') === 'dark') {
document.documentElement.setAttribute('data-bs-theme','light');
// Reset the document's background color to default
document.body.style.backgroundColor = '';
}
else {
document.documentElement.setAttribute('data-bs-theme','dark');
// Change the document's background color to black
document.body.style.backgroundColor = 'black';
}
document.getElementById('btnSwitch').addEventListener('click', function () {
var currentTheme = document.documentElement.getAttribute('data-bs-theme') === 'dark'? 'dark' : 'light';
var newTheme = currentTheme === 'dark'? 'light' : 'dark';

document.documentElement.setAttribute('data-bs-theme', newTheme);
document.body.style.backgroundColor = newTheme === 'dark'? 'black' : '';

// Send AJAX request to save preference
fetch('/preference', {
method: 'PATCH',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ prefId: 1, enabled: newTheme === 'dark' })
});
});
</script>
<script>
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/templates/player.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div th:fragment="videoPlayer" th:remove="tag">

<div class="fade-me-in">
<p class="display-6 text-muted">Now Playing</p>
<!-- <p class="display-6 text-muted">Now Playing</p>-->
<video class="img-fluid shadow-lg" controls>
<source th:src="@{'/movies/' + ${movieCode} + '/content'}" type="video/mp4">
<source th:src="@{'/movies/' + ${movieCode}}" type="video/mp4">
Expand Down
Loading

0 comments on commit ba96490

Please sign in to comment.