Skip to content

Commit

Permalink
Improve visual representation of the entries
Browse files Browse the repository at this point in the history
Entries starting the previous day or ending the next day must be distinguishable.
  • Loading branch information
raviks789 committed Apr 3, 2024
1 parent a28ca46 commit a1e3a48
Show file tree
Hide file tree
Showing 2 changed files with 207 additions and 22 deletions.
132 changes: 113 additions & 19 deletions library/Notifications/Widget/Calendar/BaseGrid.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,15 @@ abstract class BaseGrid extends BaseHtmlElement
{
use Translation;

/** @var string Continuation type of the entry continuing from the previous grid */
public const FROM_PREV_GRID = 'from-prev-grid';

/** @var string Continuation type of the entry continuing to the next grid */
public const TO_NEXT_GRID = 'to-next-grid';

/** @var string Continuation type of the entry continuing across edges of the grid */
public const ACROSS_EDGES = 'across-edges';

protected $tag = 'div';

protected $defaultAttributes = ['class' => 'calendar-grid'];
Expand Down Expand Up @@ -169,6 +178,7 @@ protected function assembleGridOverlay(BaseHtmlElement $overlay): void
$gridBorderAt = $this->getNoOfVisuallyConnectedHours() * 2;

$cellOccupiers = [];
/** @var SplObjectStorage<Entry, int[][]> $occupiedCells */
$occupiedCells = new SplObjectStorage();
foreach ($this->calendar->getEntries() as $entry) {
$actualStart = $this->roundToNearestThirtyMinute($entry->getStart());
Expand Down Expand Up @@ -236,8 +246,12 @@ protected function assembleGridOverlay(BaseHtmlElement $overlay): void

$this->extraEntriesCount = [];
foreach ($occupiedCells as $entry) {
$continuation = false;
$continuationType = null;
$rows = $occupiedCells->getInfo();
$fromPrevGrid = $gridStartsAt > $entry->getStart();
$remainingRows = count($rows);
$toNextGrid = false;

foreach ($rows as $row => $hours) {
list($rowStart, $rowSpan) = $rowPlacements[spl_object_id($entry)][$row];
$colStart = min($hours);
Expand Down Expand Up @@ -271,34 +285,71 @@ protected function assembleGridOverlay(BaseHtmlElement $overlay): void
);

$entryClass = 'area-' . implode('-', $gridArea);
$lastRow = $remainingRows === 1;

if ($lastRow) {
$toNextGrid = $gridEndsAt < $entry->getEnd();
}

$backward = $continuationType || $fromPrevGrid;
$forward = ! $lastRow || $toNextGrid;
$gradientClass = null;
if ($forward && $backward) {
$gradientClass = 'two-way-gradient';
} elseif ($backward) {
$gradientClass = 'opening-gradient';
} elseif ($forward) {
$gradientClass = 'ending-gradient';
}

$style->add(".$entryClass", [
'--entry-bg' => $entry->getAttendee()->getColor() . dechex((int) (256 * 0.1)),
'grid-area' => sprintf('~"%d / %d / %d / %d"', ...$gridArea),
'background-color' => $entry->getAttendee()->getColor() . dechex((int) (256 * 0.1)),
'border-color' => $entry->getAttendee()->getColor() . dechex((int) (256 * 0.5))
]);

$entryHtml = new HtmlElement(
'div',
Attributes::create([
'class' => ['entry', $entryClass],
'class' => ['entry', $gradientClass, $entryClass],
'data-entry-id' => $entry->getId(),
'data-row-start' => $gridArea[0],
'data-col-start' => $gridArea[1],
'data-row-end' => $gridArea[2],
'data-col-end' => $gridArea[3]
])
);
$this->assembleEntry($entryHtml, $entry, $continuation);

if ($fromPrevGrid) {
$continuationType = self::FROM_PREV_GRID;
} elseif ($toNextGrid) {
$continuationType = self::TO_NEXT_GRID;
} else {
$continuationType = self::ACROSS_EDGES;
}

$this->assembleEntry($entryHtml, $entry, $continuationType);
$overlay->addHtml($entryHtml);

$continuation = true;
$fromPrevGrid = false;
$remainingRows -= 1;
}
}
}

protected function assembleEntry(BaseHtmlElement $html, Entry $entry, bool $isContinuation): void
{
/**
* Assemble the entry in the grid
*
* @param BaseHtmlElement $html HTML element of the entry to be assembled
* @param Entry $entry Information of the entry
* @param ?string $continuationType Entry continuation type:
* null | from-previous-grid | to-next-grid | across-edges
*/
protected function assembleEntry(
BaseHtmlElement $html,
Entry $entry,
?string $continuationType
): void {
if (($url = $entry->getUrl()) !== null) {
$entryContainer = new Link(null, $url);
$html->addHtml($entryContainer);
Expand All @@ -307,7 +358,47 @@ protected function assembleEntry(BaseHtmlElement $html, Entry $entry, bool $isCo
}

$title = new HtmlElement('div', Attributes::create(['class' => 'title']));
if (! $isContinuation) {
$content = new HtmlElement(
'div',
Attributes::create(['class' => 'content'])
);

$titleAttr = $entry->getStart()->format('H:i')
. ' | ' . $entry->getAttendee()->getName()
. ': ' . $entry->getDescription();

$startText = null;
$endText = null;
if ($continuationType === self::FROM_PREV_GRID) {
$startText = $this->translate(
sprintf('starts %s', $entry->getStart()->format('d/m/y'))
);
}

if ($continuationType === self::TO_NEXT_GRID) {
$endText = $this->translate(
sprintf('ends %s', $entry->getEnd()->format('d/m/y H:i'))
);
}

if ($startText) {
$title->addHtml(
HtmlElement::create(
'div',
['class' => 'starts-at'],
$startText
)
);
$titleAttr = $startText . ' ' . $titleAttr;
}

if ($endText) {
$titleAttr = $titleAttr . ' | ' . $endText;
}

$content->addAttributes(['title' => $titleAttr]);

if ($continuationType !== null) {
$title->addHtml(new HtmlElement(
'time',
Attributes::create([
Expand All @@ -326,16 +417,7 @@ protected function assembleEntry(BaseHtmlElement $html, Entry $entry, bool $isCo
)
);

$entryContainer->addHtml(new HtmlElement(
'div',
Attributes::create(
[
'class' => 'content',
'title' => $entry->getStart()->format('H:i')
. ' | ' . $entry->getAttendee()->getName()
. ': ' . $entry->getDescription()
]
),
$content->addHtml(
$title,
new HtmlElement(
'div',
Expand All @@ -346,7 +428,19 @@ protected function assembleEntry(BaseHtmlElement $html, Entry $entry, bool $isCo
Text::create($entry->getDescription())
)
)
));
);

if ($endText) {
$content->addHtml(
HtmlElement::create(
'div',
['class' => 'ends-at'],
$endText
)
);
}

$entryContainer->addHtml($content);
}

protected function roundToNearestThirtyMinute(DateTime $time): DateTime
Expand Down
97 changes: 94 additions & 3 deletions public/css/calendar.less
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
/* Layout */

.calendar-controls {
display: flex;
justify-content: flex-start;
Expand Down Expand Up @@ -100,6 +99,7 @@
.title {
display: flex;
flex-wrap: wrap;
align-content: flex-start;
flex: 0 1 auto;
column-gap: .5em;
overflow: hidden;
Expand Down Expand Up @@ -147,6 +147,11 @@
grid-template-rows: repeat(@weeks * @rowsPerDay, 1fr);
grid-template-columns: repeat(@days * @columnsPerDay, minmax(0, 1fr));
overflow: hidden;

.ends-at {
flex: 1 1 0;
text-align: right;
}
}

.step {
Expand Down Expand Up @@ -183,6 +188,10 @@
.grid,
.overlay {
border-left: none;

.title {
width: 100%;
}
}

.step {
Expand Down Expand Up @@ -220,6 +229,22 @@
}
}

.calendar-grid.week,
.calendar-grid.day {
.entry {
.content {
flex-direction: column;
align-content: flex-start;
justify-content: flex-end;

.ends-at {
text-align: right;
width: 100%;
}
}
}
}

.calendar-grid {
display: grid;

Expand Down Expand Up @@ -258,6 +283,17 @@

.entry {
pointer-events: all;

.starts-at,
.ends-at {
font-weight: normal;
color: @text-color-light;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
font-size: 11/12em;
line-height: 12/11 * 1.5;
}
}
}
}
Expand All @@ -283,6 +319,53 @@
font-weight: normal;
}

.calendar-grid.month {
.entry {
&.two-way-gradient {
border-radius: 0;
border-right: none;
border-left: none;
background: linear-gradient(to right, transparent, var(--entry-bg) 0.5em, var(--entry-bg) calc(100% - 0.5em), transparent);
}

&.opening-gradient {
border-radius: 0 0.25em 0.25em 0;
border-left: none;
background: linear-gradient(to left, var(--entry-bg) calc(100% - 1em), transparent);
}

&.ending-gradient {
border-radius: 0.25em 0 0 0.25em;
border-right: none;
background: linear-gradient(to right, var(--entry-bg) calc(100% - 1em), transparent);
}
}
}

.calendar-grid.week,
.calendar-grid.day{
.entry {
&.two-way-gradient {
border-radius: 0;
border-top: none;
border-bottom: none;
background: linear-gradient(to bottom, transparent, var(--entry-bg) 0.5em, var(--entry-bg) calc(100% - 0.5em), transparent);
}

&.opening-gradient {
border-radius: 0 0 0.25em 0.25em;
border-top: none;
background: linear-gradient(to top, var(--entry-bg) calc(100% - 1em), transparent);
}

&.ending-gradient {
border-radius: 0.25em 0.25em 0 0;
border-bottom: none;
background: linear-gradient(to bottom, var(--entry-bg) calc(100% - 1em), transparent);
}
}
}

.grid {
background-color: @gray-lighter;
border-color: @gray-lighter;
Expand All @@ -303,6 +386,7 @@
.entry {
border-width: 1px;
border-style: solid;
background-color: var(--entry-bg);
.rounded-corners();

a:hover {
Expand All @@ -324,6 +408,10 @@
opacity: .8;
}
}

.description {
mix-blend-mode: screen;
}
}

.column-title {
Expand All @@ -344,7 +432,10 @@
}

@light-mode: {
.calendar .entry .title {
mix-blend-mode: multiply;
.calendar .entry {
.title,
.description {
mix-blend-mode: multiply;
}
}
};

0 comments on commit a1e3a48

Please sign in to comment.