diff --git a/app/Activity/Controllers/WatchController.php b/app/Activity/Controllers/WatchController.php index a297aaafc..e0596864c 100644 --- a/app/Activity/Controllers/WatchController.php +++ b/app/Activity/Controllers/WatchController.php @@ -3,7 +3,7 @@ namespace BookStack\Activity\Controllers; use BookStack\Activity\Models\Watch; -use BookStack\Activity\Tools\UserWatchOptions; +use BookStack\Activity\Tools\UserEntityWatchOptions; use BookStack\App\Model; use BookStack\Entities\Models\Entity; use BookStack\Http\Controller; @@ -20,8 +20,8 @@ class WatchController extends Controller ]); $watchable = $this->getValidatedModelFromRequest($request); - $watchOptions = new UserWatchOptions(user()); - $watchOptions->updateEntityWatchLevel($watchable, $requestData['level']); + $watchOptions = new UserEntityWatchOptions(user(), $watchable); + $watchOptions->updateWatchLevel($requestData['level']); $this->showSuccessNotification(trans('activities.watch_update_level_notification')); diff --git a/app/Activity/Tools/UserEntityWatchOptions.php b/app/Activity/Tools/UserEntityWatchOptions.php new file mode 100644 index 000000000..26d830851 --- /dev/null +++ b/app/Activity/Tools/UserEntityWatchOptions.php @@ -0,0 +1,124 @@ +user->can('receive-notifications') && !$this->user->isDefault(); + } + + public function getWatchLevel(): string + { + return WatchLevels::levelValueToName($this->getWatchLevelValue()); + } + + public function isWatching(): bool + { + return $this->getWatchLevelValue() !== WatchLevels::DEFAULT; + } + + public function getWatchedParent(): ?WatchedParentDetails + { + $watchMap = $this->getWatchMap(); + unset($watchMap[$this->entity->getMorphClass()]); + + if (isset($watchMap['chapter'])) { + return new WatchedParentDetails('chapter', $watchMap['chapter']); + } + + if (isset($watchMap['book'])) { + return new WatchedParentDetails('book', $watchMap['book']); + } + + return null; + } + + public function updateWatchLevel(string $level): void + { + $levelValue = WatchLevels::levelNameToValue($level); + if ($levelValue < 0) { + $this->remove(); + return; + } + + $this->updateLevel($levelValue); + } + + public function getWatchMap(): array + { + if (!is_null($this->watchMap)) { + return $this->watchMap; + } + + $entities = [$this->entity]; + if ($this->entity instanceof BookChild) { + $entities[] = $this->entity->book; + } + if ($this->entity instanceof Page && $this->entity->chapter) { + $entities[] = $this->entity->chapter; + } + + $query = Watch::query()->where(function (Builder $subQuery) use ($entities) { + foreach ($entities as $entity) { + $subQuery->orWhere(function (Builder $whereQuery) use ($entity) { + $whereQuery->where('watchable_type', '=', $entity->getMorphClass()) + ->where('watchable_id', '=', $entity->id); + }); + } + }); + + $this->watchMap = $query->get(['watchable_type', 'level']) + ->pluck('level', 'watchable_type') + ->toArray(); + + return $this->watchMap; + } + + protected function getWatchLevelValue() + { + return $this->getWatchMap()[$this->entity->getMorphClass()] ?? WatchLevels::DEFAULT; + } + + protected function updateLevel(int $levelValue): void + { + Watch::query()->updateOrCreate([ + 'watchable_id' => $this->entity->id, + 'watchable_type' => $this->entity->getMorphClass(), + 'user_id' => $this->user->id, + ], [ + 'level' => $levelValue, + ]); + $this->watchMap = null; + } + + protected function remove(): void + { + $this->entityQuery()->delete(); + $this->watchMap = null; + } + + protected function entityQuery(): Builder + { + return Watch::query()->where('watchable_id', '=', $this->entity->id) + ->where('watchable_type', '=', $this->entity->getMorphClass()) + ->where('user_id', '=', $this->user->id); + } +} diff --git a/app/Activity/Tools/UserWatchOptions.php b/app/Activity/Tools/UserWatchOptions.php deleted file mode 100644 index 64c5f317f..000000000 --- a/app/Activity/Tools/UserWatchOptions.php +++ /dev/null @@ -1,67 +0,0 @@ -user->can('receive-notifications') && !$this->user->isDefault(); - } - - public function getEntityWatchLevel(Entity $entity): string - { - $levelValue = $this->entityQuery($entity)->first(['level'])->level ?? -1; - return WatchLevels::levelValueToName($levelValue); - } - - public function isWatching(Entity $entity): bool - { - return $this->entityQuery($entity)->exists(); - } - - public function updateEntityWatchLevel(Entity $entity, string $level): void - { - $levelValue = WatchLevels::levelNameToValue($level); - if ($levelValue < 0) { - $this->removeForEntity($entity); - return; - } - - $this->updateForEntity($entity, $levelValue); - } - - protected function updateForEntity(Entity $entity, int $levelValue): void - { - Watch::query()->updateOrCreate([ - 'watchable_id' => $entity->id, - 'watchable_type' => $entity->getMorphClass(), - 'user_id' => $this->user->id, - ], [ - 'level' => $levelValue, - ]); - } - - protected function removeForEntity(Entity $entity): void - { - $this->entityQuery($entity)->delete(); - } - - protected function entityQuery(Entity $entity): Builder - { - return Watch::query()->where('watchable_id', '=', $entity->id) - ->where('watchable_type', '=', $entity->getMorphClass()) - ->where('user_id', '=', $this->user->id); - } -} diff --git a/app/Activity/Tools/WatchedParentDetails.php b/app/Activity/Tools/WatchedParentDetails.php new file mode 100644 index 000000000..5a881c04f --- /dev/null +++ b/app/Activity/Tools/WatchedParentDetails.php @@ -0,0 +1,19 @@ +level === WatchLevels::IGNORE; + } +} diff --git a/app/Entities/Controllers/BookController.php b/app/Entities/Controllers/BookController.php index 3ce71c38a..55d28c684 100644 --- a/app/Entities/Controllers/BookController.php +++ b/app/Entities/Controllers/BookController.php @@ -5,7 +5,7 @@ namespace BookStack\Entities\Controllers; use BookStack\Activity\ActivityQueries; use BookStack\Activity\ActivityType; use BookStack\Activity\Models\View; -use BookStack\Activity\Tools\UserWatchOptions; +use BookStack\Activity\Tools\UserEntityWatchOptions; use BookStack\Entities\Models\Bookshelf; use BookStack\Entities\Repos\BookRepo; use BookStack\Entities\Tools\BookContents; @@ -139,7 +139,7 @@ class BookController extends Controller 'current' => $book, 'bookChildren' => $bookChildren, 'bookParentShelves' => $bookParentShelves, - 'watchOptions' => new UserWatchOptions(user()), + 'watchOptions' => new UserEntityWatchOptions(user(), $book), 'activity' => $activities->entityActivity($book, 20, 1), 'referenceCount' => $this->referenceFetcher->getPageReferenceCountToEntity($book), ]); diff --git a/app/Entities/Controllers/ChapterController.php b/app/Entities/Controllers/ChapterController.php index c28db3800..ee1df0581 100644 --- a/app/Entities/Controllers/ChapterController.php +++ b/app/Entities/Controllers/ChapterController.php @@ -3,7 +3,7 @@ namespace BookStack\Entities\Controllers; use BookStack\Activity\Models\View; -use BookStack\Activity\Tools\UserWatchOptions; +use BookStack\Activity\Tools\UserEntityWatchOptions; use BookStack\Entities\Models\Book; use BookStack\Entities\Repos\ChapterRepo; use BookStack\Entities\Tools\BookContents; @@ -82,7 +82,7 @@ class ChapterController extends Controller 'chapter' => $chapter, 'current' => $chapter, 'sidebarTree' => $sidebarTree, - 'watchOptions' => new UserWatchOptions(user()), + 'watchOptions' => new UserEntityWatchOptions(user(), $chapter), 'pages' => $pages, 'next' => $nextPreviousLocator->getNext(), 'previous' => $nextPreviousLocator->getPrevious(), diff --git a/app/Entities/Controllers/PageController.php b/app/Entities/Controllers/PageController.php index dad05d034..624931065 100644 --- a/app/Entities/Controllers/PageController.php +++ b/app/Entities/Controllers/PageController.php @@ -4,7 +4,7 @@ namespace BookStack\Entities\Controllers; use BookStack\Activity\Models\View; use BookStack\Activity\Tools\CommentTree; -use BookStack\Activity\Tools\UserWatchOptions; +use BookStack\Activity\Tools\UserEntityWatchOptions; use BookStack\Entities\Models\Page; use BookStack\Entities\Repos\PageRepo; use BookStack\Entities\Tools\BookContents; @@ -152,7 +152,7 @@ class PageController extends Controller 'sidebarTree' => $sidebarTree, 'commentTree' => $commentTree, 'pageNav' => $pageNav, - 'watchOptions' => new UserWatchOptions(user()), + 'watchOptions' => new UserEntityWatchOptions(user(), $page), 'next' => $nextPreviousLocator->getNext(), 'previous' => $nextPreviousLocator->getPrevious(), 'referenceCount' => $this->referenceFetcher->getPageReferenceCountToEntity($page), diff --git a/lang/en/entities.php b/lang/en/entities.php index 87c09634b..f1e7dcc01 100644 --- a/lang/en/entities.php +++ b/lang/en/entities.php @@ -421,4 +421,8 @@ return [ 'watch_detail_new' => 'Watching for new pages', 'watch_detail_updates' => 'Watching new pages and updates', 'watch_detail_comments' => 'Watching new pages, updates & comments', + 'watch_detail_parent_book' => 'Watching via parent book', + 'watch_detail_parent_book_ignore' => 'Ignoring via parent book', + 'watch_detail_parent_chapter' => 'Watching via parent chapter', + 'watch_detail_parent_chapter_ignore' => 'Ignoring via parent chapter', ]; diff --git a/resources/views/books/show.blade.php b/resources/views/books/show.blade.php index b52a103a4..0fb98e304 100644 --- a/resources/views/books/show.blade.php +++ b/resources/views/books/show.blade.php @@ -139,7 +139,7 @@
- @if($watchOptions->canWatch() && !$watchOptions->isWatching($book)) + @if($watchOptions->canWatch() && !$watchOptions->isWatching()) @include('entities.watch-action', ['entity' => $book]) @endif @if(signedInUser()) diff --git a/resources/views/chapters/show.blade.php b/resources/views/chapters/show.blade.php index 3b1cfb07c..67a8b9fa5 100644 --- a/resources/views/chapters/show.blade.php +++ b/resources/views/chapters/show.blade.php @@ -157,7 +157,7 @@
- @if($watchOptions->canWatch() && !$watchOptions->isWatching($chapter)) + @if($watchOptions->canWatch() && !$watchOptions->isWatching()) @include('entities.watch-action', ['entity' => $chapter]) @endif @if(signedInUser()) diff --git a/resources/views/entities/meta.blade.php b/resources/views/entities/meta.blade.php index 6783902a1..2298be8bb 100644 --- a/resources/views/entities/meta.blade.php +++ b/resources/views/entities/meta.blade.php @@ -69,17 +69,21 @@ @endif - @if($watchOptions?->canWatch() && $watchOptions->isWatching($entity)) - @php - $watchLevel = $watchOptions->getEntityWatchLevel($entity); - @endphp - + @if($watchOptions?->canWatch()) + @if($watchOptions->isWatching()) + @include('entities.watch-controls', [ + 'entity' => $entity, + 'watchLevel' => $watchOptions->getWatchLevel(), + 'label' => trans('entities.watch_detail_' . $watchOptions->getWatchLevel()), + 'ignoring' => $watchOptions->getWatchLevel() === 'ignore', + ]) + @elseif($watchedParent = $watchOptions->getWatchedParent()) + @include('entities.watch-controls', [ + 'entity' => $entity, + 'watchLevel' => $watchOptions->getWatchLevel(), + 'label' => trans('entities.watch_detail_parent_' . $watchedParent->type . ($watchedParent->ignoring() ? '_ignore' : '')), + 'ignoring' => $watchedParent->ignoring(), + ]) + @endif @endif \ No newline at end of file diff --git a/resources/views/entities/watch-controls.blade.php b/resources/views/entities/watch-controls.blade.php index 5ad6108a0..4fdda5347 100644 --- a/resources/views/entities/watch-controls.blade.php +++ b/resources/views/entities/watch-controls.blade.php @@ -1,35 +1,42 @@ -
- {{ method_field('PUT') }} - {{ csrf_field() }} - - + - - + + +
  • +
    +
  • + @endforeach
  • -
    + {{ trans('entities.watch_change_default') }}
  • - @endforeach -
  • - {{ trans('entities.watch_change_default') }} -
  • - -
    \ No newline at end of file + + + \ No newline at end of file diff --git a/resources/views/pages/show.blade.php b/resources/views/pages/show.blade.php index aefcb96e1..7d44f677d 100644 --- a/resources/views/pages/show.blade.php +++ b/resources/views/pages/show.blade.php @@ -185,7 +185,7 @@
    - @if($watchOptions->canWatch() && !$watchOptions->isWatching($page)) + @if($watchOptions->canWatch() && !$watchOptions->isWatching()) @include('entities.watch-action', ['entity' => $page]) @endif @if(signedInUser())