Skip to content

Commit

Permalink
Merge pull request #548 from leepeuker/add-watch-date-position
Browse files Browse the repository at this point in the history
Add optional position to watch dates
  • Loading branch information
leepeuker authored Dec 11, 2023
2 parents fa176fc + de1371d commit 829d0a8
Show file tree
Hide file tree
Showing 14 changed files with 250 additions and 60 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php declare(strict_types=1);

use Phinx\Migration\AbstractMigration;

final class AddPositionToUserWatchDatesTable extends AbstractMigration
{
public function down() : void
{
$this->execute(
<<<SQL
ALTER TABLE movie_user_watch_dates DROP COLUMN position;
SQL,
);
}

public function up() : void
{
$this->execute(
<<<SQL
ALTER TABLE movie_user_watch_dates ADD COLUMN position SMALLINT DEFAULT 1 NOT NULL AFTER comment;
SQL,
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php declare(strict_types=1);

use Phinx\Migration\AbstractMigration;

final class AddPositionToUserWatchDatesTable extends AbstractMigration
{
public function down() : void
{
$this->execute(
<<<SQL
CREATE TABLE `movie_user_watch_dates_tmp` (
`movie_id` INTEGER NOT NULL,
`user_id` INTEGER NOT NULL,
`watched_at` TEXT NOT NULL,
`plays` INTEGER DEFAULT 1,
`comment` TEXT DEFAULT NULL,
FOREIGN KEY (`user_id`) REFERENCES user (`id`) ON DELETE CASCADE,
FOREIGN KEY (`movie_id`) REFERENCES movie (`id`) ON DELETE CASCADE
)
SQL,
);
$this->execute(
'INSERT INTO `movie_user_watch_dates_tmp` (movie_id, user_id, watched_at, plays, comment)
SELECT movie_id, user_id, watched_at, plays, comment FROM movie_user_watch_dates',
);
$this->execute('DROP TABLE `movie_user_watch_dates`');
$this->execute('ALTER TABLE `movie_user_watch_dates_tmp` RENAME TO `movie_user_watch_dates`');
}

public function up() : void
{
$this->execute(
<<<SQL
CREATE TABLE `movie_user_watch_dates_tmp` (
`movie_id` INTEGER NOT NULL,
`user_id` INTEGER NOT NULL,
`watched_at` TEXT,
`plays` INTEGER DEFAULT 1,
`comment` TEXT DEFAULT NULL,
`position` INTEGER NOT NULL DEFAULT 1,
FOREIGN KEY (`user_id`) REFERENCES user (`id`) ON DELETE CASCADE,
FOREIGN KEY (`movie_id`) REFERENCES movie (`id`) ON DELETE CASCADE
)
SQL,
);
$this->execute(
'INSERT INTO `movie_user_watch_dates_tmp` (movie_id, user_id, watched_at, plays, comment)
SELECT * FROM movie_user_watch_dates',
);
$this->execute('DROP TABLE `movie_user_watch_dates`');
$this->execute('ALTER TABLE `movie_user_watch_dates_tmp` RENAME TO `movie_user_watch_dates`');
}
}
18 changes: 18 additions & 0 deletions docs/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,9 @@
},
"comment": {
"$ref": "#/components/schemas/commentOptional"
},
"position": {
"$ref": "#/components/schemas/positionOptional"
}
}
}
Expand Down Expand Up @@ -211,6 +214,9 @@
},
"comment": {
"$ref": "#/components/schemas/comment"
},
"position": {
"$ref": "#/components/schemas/position"
}
}
}
Expand Down Expand Up @@ -1199,6 +1205,18 @@
"default": null,
"required": false
},
"position": {
"type": "number",
"example": 1,
"nullable": false
},
"positionOptional": {
"type": "number",
"example": 1,
"nullable": true,
"default": 1,
"required": false
},
"date": {
"type": "string",
"example": "2023-07-02"
Expand Down
38 changes: 36 additions & 2 deletions public/js/movie.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,32 @@ function deleteWatchDate() {
})
}

function toggleWatchDateAdvancedMode() {
if (document.getElementById('advancedWatchDateDetails').classList.contains('d-none')) {
enableWatchDateAdvancedMode()

return
}

disableWatchDateAdvancedMode()
}

function disableWatchDateAdvancedMode() {
const advancedWatchDateDetails = document.getElementById('advancedWatchDateDetails');
const advancedWatchDateModeButton = document.getElementById('advancedWatchDateModeButton');

advancedWatchDateModeButton.innerHTML = 'Advanced mode'
advancedWatchDateDetails.classList.add('d-none')
}

function enableWatchDateAdvancedMode() {
const advancedWatchDateDetails = document.getElementById('advancedWatchDateDetails');
const advancedWatchDateModeButton = document.getElementById('advancedWatchDateModeButton');

advancedWatchDateDetails.classList.remove('d-none')
advancedWatchDateModeButton.innerHTML = 'Simple mode'
}

function getMovieId() {
return document.getElementById('movieId').value
}
Expand Down Expand Up @@ -77,10 +103,13 @@ function loadWatchDateModal(watchDateListElement) {
document.getElementById('editWatchDateModalInput').value = watchDateListElement.dataset.watchDate;
document.getElementById('editWatchDateModalPlaysInput').value = watchDateListElement.dataset.plays;
document.getElementById('editWatchDateModalCommentInput').value = watchDateListElement.dataset.comment;
document.getElementById('editWatchDateModalPositionInput').value = watchDateListElement.dataset.position;

document.getElementById('originalWatchDate').value = watchDateListElement.dataset.watchDate;
document.getElementById('originalWatchDatePlays').value = watchDateListElement.dataset.plays;

disableWatchDateAdvancedMode()

new Datepicker(document.getElementById('editWatchDateModalInput'), {
format: document.getElementById('dateFormatJavascript').value,
title: 'Watch date',
Expand All @@ -94,6 +123,7 @@ function editWatchDate() {

const newWatchDate = document.getElementById('editWatchDateModalInput').value;
const newWatchDatePlays = document.getElementById('editWatchDateModalPlaysInput').value;
const newPositionPlays = document.getElementById('editWatchDateModalPositionInput').value;
const comment = document.getElementById('editWatchDateModalCommentInput').value;

const apiUrl = '/users/' + getRouteUsername() + '/movies/' + getMovieId() + '/history'
Expand All @@ -106,6 +136,7 @@ function editWatchDate() {
'originalWatchDate': originalWatchDate,
'plays': newWatchDatePlays,
'comment': comment,
'position': newPositionPlays,
'dateFormat': document.getElementById('dateFormatPhp').value
}),
success: function (data, textStatus, xhr) {
Expand Down Expand Up @@ -344,8 +375,8 @@ function isTruncated(el) {
return el.scrollWidth > el.clientWidth
}

const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]')
const tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl => {
const tooltipTriggerListCast = document.querySelectorAll('[data-bs-toggle="tooltip"]#castMemberName, [data-bs-toggle="tooltip"]#castCharacterName')
const tooltipCastList = [...tooltipTriggerListCast].map(tooltipTriggerEl => {
if (isTruncated(tooltipTriggerEl) === false) {
return
}
Expand All @@ -357,3 +388,6 @@ const tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl => {

new bootstrap.Tooltip(tooltipTriggerEl, {'placement': placement})
})

const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]#editWatchDateModalPlays, [data-bs-toggle="tooltip"]#editWatchDateModalPlaysInput1')
const tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl))
77 changes: 43 additions & 34 deletions src/Domain/Movie/History/MovieHistoryApi.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,13 @@ public function __construct(
) {
}

public function create(int $movieId, int $userId, ?Date $watchedAt, int $plays, ?string $comment = null) : void
public function create(int $movieId, int $userId, ?Date $watchedAt, int $plays, ?int $position = null, ?string $comment = null) : void
{
$this->repository->create($movieId, $userId, $watchedAt, $plays, $comment);
if ($position === null) {
$position = $this->findHighestPositionForWatchDate($movieId, $userId, $watchedAt);
}

$this->repository->create($movieId, $userId, $watchedAt, $plays, $comment, (int)$position + 1);

if ($this->userApi->fetchUser($userId)->hasJellyfinSyncEnabled() === false) {
return;
Expand All @@ -35,6 +39,11 @@ public function create(int $movieId, int $userId, ?Date $watchedAt, int $plays,
$this->jobQueueApi->addJellyfinExportMoviesJob($userId, [$movieId]);
}

public function findHighestPositionForWatchDate(int $movieIdToIgnore, int $userId, ?Date $watchedAt) : ?int
{
return $this->repository->fetchHighestPositionForWatchDate($movieIdToIgnore, $userId, $watchedAt);
}

public function deleteByUserAndMovieId(int $userId, int $movieId) : void
{
$this->repository->deleteByUserAndMovieId($userId, $movieId);
Expand Down Expand Up @@ -241,6 +250,36 @@ public function fetchMovieIdsWithWatchDatesByUserId(int $userId) : array
return $this->movieRepository->fetchMovieIdsWithWatchDatesByUserId($userId);
}

public function fetchPlayedMoviesPaginated(
int $userId,
int $limit,
int $page,
?string $searchTerm = null,
string $sortBy = 'title',
?SortOrder $sortOrder = null,
?Year $releaseYear = null,
?string $language = null,
?string $genre = null,
) : array {
if ($sortOrder === null) {
$sortOrder = SortOrder::createAsc();
}

$movies = $this->movieRepository->fetchUniqueWatchedMoviesPaginated(
$userId,
$limit,
$page,
$searchTerm,
$sortBy,
$sortOrder,
$releaseYear,
$language,
$genre,
);

return $this->urlGenerator->replacePosterPathWithImageSrcUrl($movies);
}

public function fetchTmdbIdsToLastWatchDatesMap(int $userId, array $tmdbIds) : array
{
$map = [];
Expand Down Expand Up @@ -386,36 +425,6 @@ public function fetchUniqueWatchedMoviesPaginated(
return $this->urlGenerator->replacePosterPathWithImageSrcUrl($movies);
}

public function fetchPlayedMoviesPaginated(
int $userId,
int $limit,
int $page,
?string $searchTerm = null,
string $sortBy = 'title',
?SortOrder $sortOrder = null,
?Year $releaseYear = null,
?string $language = null,
?string $genre = null,
) : array {
if ($sortOrder === null) {
$sortOrder = SortOrder::createAsc();
}

$movies = $this->movieRepository->fetchUniqueWatchedMoviesPaginated(
$userId,
$limit,
$page,
$searchTerm,
$sortBy,
$sortOrder,
$releaseYear,
$language,
$genre,
);

return $this->urlGenerator->replacePosterPathWithImageSrcUrl($movies);
}

public function fetchWatchDatesForMovieIds(int $userId, array $movieIds) : array
{
$watchDates = [];
Expand All @@ -440,9 +449,9 @@ public function findHistoryEntryForMovieByUserOnDate(int $movieId, int $userId,
return $this->movieRepository->findHistoryEntryForMovieByUserOnDate($movieId, $userId, $watchedAt);
}

public function update(int $movieId, int $userId, ?Date $watchedAt, int $plays, ?string $comment = null) : void
public function update(int $movieId, int $userId, ?Date $watchedAt, int $plays, int $position, ?string $comment = null) : void
{
$this->repository->update($movieId, $userId, $watchedAt, $plays, $comment);
$this->repository->update($movieId, $userId, $watchedAt, $plays, $position, $comment);
}

public function updateHistoryComment(int $movieId, int $userId, ?Date $watchAt, ?string $comment) : void
Expand Down
7 changes: 7 additions & 0 deletions src/Domain/Movie/History/MovieHistoryEntity.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ private function __construct(
private readonly int $movieId,
private readonly ?Date $watchedAt,
private readonly int $plays,
private readonly int $position,
private readonly ?string $comment,
) {
}
Expand All @@ -20,6 +21,7 @@ public static function createFromArray(array $data) : self
(int)$data['movie_id'],
$data['watched_at'] == null ? null : Date::createFromString($data['watched_at']),
$data['plays'],
$data['position'],
$data['comment'],
);
}
Expand All @@ -39,6 +41,11 @@ public function getPlays() : int
return $this->plays;
}

public function getPosition() : int
{
return $this->position;
}

public function getWatchedAt() : ?Date
{
return $this->watchedAt;
Expand Down
Loading

0 comments on commit 829d0a8

Please sign in to comment.