diff --git a/assets/sass/_variables.scss b/assets/sass/_variables.scss index 71cbe5a..dc7852c 100644 --- a/assets/sass/_variables.scss +++ b/assets/sass/_variables.scss @@ -3,6 +3,10 @@ --color-foreground: #D3D7CF; --color-blue-light: #9CD9F0; --color-blue-dark: #72B3CC; + --color-green-light: #CDEE69; + --color-green-dark: #8EB33B; + --color-yellow-light: #FFE377; + --color-yellow-dark: #D0B03C; --color-black-light: #5D5D5D; --color-black-dark: #000000; --color-white-light: #F7F7F7; diff --git a/assets/sass/components/_content.scss b/assets/sass/components/_content.scss index 8b51a5e..7eb90d8 100644 --- a/assets/sass/components/_content.scss +++ b/assets/sass/components/_content.scss @@ -5,4 +5,5 @@ body > main { } } +@import 'content/flash'; @import 'content/entries'; diff --git a/assets/sass/components/content/_flash.scss b/assets/sass/components/content/_flash.scss new file mode 100644 index 0000000..430d1d2 --- /dev/null +++ b/assets/sass/components/content/_flash.scss @@ -0,0 +1,20 @@ +body > aside { + ul { + list-style: none; + color: var(--color-black-dark); + margin: var(--spacing-elements); + + li { + padding: var(--spacing-small-elements); + } + + &.success { + background-color: var(--color-green-dark); + border: var(--color-green-light) solid var(--width-border-default); + } + &.notice { + background-color: var(--color-yellow-dark); + border: var(--color-yellow-light) solid var(--width-border-default); + } + } +} diff --git a/config/routes.yaml b/config/routes.yaml index f6d5ae1..33d8948 100644 --- a/config/routes.yaml +++ b/config/routes.yaml @@ -17,3 +17,11 @@ feed: entry: path: /entry/{slug} controller: App\Controller\EntryController::show + +entry-mark-as-read: + path: /entry/{slug}/mark/read + controller: App\Controller\EntryController::read + +entry-mark-as-un-read: + path: /entry/{slug}/mark/un-read + controller: App\Controller\EntryController::unRead diff --git a/public/css/style.css b/public/css/style.css index 208e190..a832f3e 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -3,6 +3,10 @@ --color-foreground: #D3D7CF; --color-blue-light: #9CD9F0; --color-blue-dark: #72B3CC; + --color-green-light: #CDEE69; + --color-green-dark: #8EB33B; + --color-yellow-light: #FFE377; + --color-yellow-dark: #D0B03C; --color-black-light: #5D5D5D; --color-black-dark: #000000; --color-white-light: #F7F7F7; @@ -56,6 +60,19 @@ body > main { body > main header h1 { margin: 0; } +body > aside ul { + list-style: none; + color: var(--color-black-dark); + margin: var(--spacing-elements); } + body > aside ul li { + padding: var(--spacing-small-elements); } + body > aside ul.success { + background-color: var(--color-green-dark); + border: var(--color-green-light) solid var(--width-border-default); } + body > aside ul.notice { + background-color: var(--color-yellow-dark); + border: var(--color-yellow-light) solid var(--width-border-default); } + article { display: grid; grid-template-columns: 50em var(--width-sidebar-max); diff --git a/src/Controller/EntryController.php b/src/Controller/EntryController.php index f579517..08e18cd 100644 --- a/src/Controller/EntryController.php +++ b/src/Controller/EntryController.php @@ -3,14 +3,64 @@ namespace App\Controller; use App\Entity\Entry; +use Doctrine\ORM\EntityManagerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; class EntryController extends AbstractController { - public function show(Entry $entry) + /** + * @var EntityManagerInterface + */ + private $entityManager; + + public function __construct( + EntityManagerInterface $entityManager + ) { + $this->entityManager = $entityManager; + } + + public function show(Entry $entry): Response { return $this->render('entry/show.html.twig', [ 'entry' => $entry, ]); } + + public function read(Entry $entry, Request $request): Response + { + if ($entry->wasRead()) { + $this->addFlash('notice', sprintf('Entry "%s" was already marked as read.', $entry->getName())); + } else { + $entry->markAsRead(); + $this->entityManager->flush(); + $this->addFlash('success', sprintf('Entry "%s" was marked as read.', $entry->getName())); + } + + return $this->getRedirectResponseAfterModification($request); + } + + public function unRead(Entry $entry, Request $request): Response + { + if ($entry->wasRead()) { + $entry->markAsUnRead(); + $this->entityManager->flush(); + $this->addFlash('success', sprintf('Entry "%s" was marked as un read.', $entry->getName())); + } else { + $this->addFlash('notice', sprintf('Entry "%s" was not yet marked as read.', $entry->getName())); + } + + return $this->getRedirectResponseAfterModification($request); + } + + private function getRedirectResponseAfterModification(Request $request): Response + { + $redirectTarget = $request->headers->get('referer'); + if (is_string($redirectTarget)) { + return $this->redirect($redirectTarget, 307); + } + + return $this->redirectToRoute('start', [], 307); + } } diff --git a/src/Entity/Bucket.php b/src/Entity/Bucket.php index 582a16a..3410451 100644 --- a/src/Entity/Bucket.php +++ b/src/Entity/Bucket.php @@ -5,6 +5,7 @@ namespace App\Entity; use App\Repository\BucketRepository; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; +use Doctrine\Common\Collections\Criteria; use Doctrine\ORM\Mapping as ORM; /** @@ -59,9 +60,6 @@ class Bucket return $this->slug; } - /** - * @return Collection|Feed[] - */ public function getFeeds(): Collection { return $this->feeds; diff --git a/src/Entity/Entry.php b/src/Entity/Entry.php index 1c5c40c..66d15c9 100644 --- a/src/Entity/Entry.php +++ b/src/Entity/Entry.php @@ -128,9 +128,18 @@ class Entry return $this->content; } - // TODO: Rename into is / was ? - public function getRead(): bool + public function wasRead(): bool { return $this->read; } + + public function markAsRead(): void + { + $this->read = true; + } + + public function markAsUnRead(): void + { + $this->read = false; + } } diff --git a/src/Entity/Feed.php b/src/Entity/Feed.php index fce96fd..38de218 100644 --- a/src/Entity/Feed.php +++ b/src/Entity/Feed.php @@ -5,6 +5,7 @@ namespace App\Entity; use App\Repository\FeedRepository; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; +use Doctrine\Common\Collections\Criteria; use Doctrine\ORM\Mapping as ORM; /** @@ -100,4 +101,11 @@ class Feed { return $this->entries; } + + public function getUnreadEntries(): Collection + { + $criteria = Criteria::create(); + $criteria->where(Criteria::expr()->eq('read', false)); + return $this->entries->matching($criteria); + } } diff --git a/templates/base.html.twig b/templates/base.html.twig index 650e014..82bb885 100644 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -12,6 +12,16 @@

{{ app_name }}

+ +
{% block body %}{% endblock %}
diff --git a/templates/bucket/show.html.twig b/templates/bucket/show.html.twig index 67648bb..f8ed1e6 100644 --- a/templates/bucket/show.html.twig +++ b/templates/bucket/show.html.twig @@ -9,7 +9,7 @@ {# TODO: collect newest entries of all feeds in controller #} - {{ include('feed/entries.html.twig', {entries: bucket.feeds.first.entries | slice(0, 10) }) }} + {{ include('feed/entries.html.twig', {entries: bucket.feeds.first.unreadEntries | slice(0, 10) }) }}