Add wish list view

This commit is contained in:
grandeljay 2022-11-20 10:40:30 +01:00
parent b946262029
commit 24082c5cff
11 changed files with 536 additions and 292 deletions

View file

@ -94,12 +94,14 @@ switch ($_SERVER['REQUEST_METHOD']) {
break;
case 'GET':
if (isset($_GET['wishlist'], $_GET['priority'])) {
if (isset($_GET['wishlist_id'], $_GET['priority'])) {
/**
* Get wishlist cards
* Get wishlist cards with priority
*/
$wishlist = new Wishlist($_GET['wishlist']);
$options = array();
$wishlist = new Wishlist($_GET['wishlist_id']);
$options = array(
'style' => $_GET['style'],
);
$where = array(
'wishlist' => '`wishlist` = ' . $wishlist->id,
'priority' => '`priority` = ' . $_GET['priority'],
@ -113,9 +115,7 @@ switch ($_SERVER['REQUEST_METHOD']) {
$where['priority'] = '`priority` IS NULL';
}
$options = array(
'WHERE' => '(' . implode(') AND (', $where) . ')',
);
$options['WHERE'] = '(' . implode(') AND (', $where) . ')';
$response['results'] = $wishlist->getCards($options);
} elseif (isset($_GET['userid']) || isset($_SESSION['user']->id)) {
@ -124,24 +124,24 @@ switch ($_SERVER['REQUEST_METHOD']) {
*/
$user = isset($_GET['userid']) ? User::getFromID($_GET['userid']) : $_SESSION['user'];
$wishlists = $user->getWishlists();
$wishlists = array_map(
function ($dataWishlist) {
/**
* Format wishlists to fit FUI dropdown
*/
$data = $dataWishlist;
$data['value'] = $dataWishlist['id'];
$data['text'] = $dataWishlist['name'];
$wishlist = new Wishlist($dataWishlist['id']);
$data['cards'] = $wishlist->getCards();
return $data;
},
$wishlists
$wishlists = array();
$options = array(
'style' => $_GET['style'],
);
foreach ($user->getWishlists() as $wishlist_result) {
$wishlist = new Wishlist($wishlist_result['id']);
$wishlists[$wishlist->id] = array(
'name' => $wishlist->name,
'value' => $wishlist->id,
'text' => $wishlist->name,
'cards' => $wishlist->getCards($options),
'hash' => $wishlist->hash,
);
}
$response['results'] = $wishlists;
}
break;

View file

@ -1,6 +1,6 @@
:root {
--lineHeight: 1.4285;
--wishPreviewHeight: min(30vh, 192px);
--wishPreviewHeight: 192px;
--dimmerZIndex: 100;
}
@ -71,12 +71,32 @@ figure {
margin: 0;
}
/**
* Wishlist Grid
*/
@media (max-width: 767.98px) {
.ui.grid > .stackable.stackable.stackable.row > .column,
.ui.stackable.grid > .column.grid > .column,
.ui.stackable.grid > .column.row > .column,
.ui.stackable.grid > .column:not(.row),
.ui.stackable.grid > .row > .column,
.ui.stackable.grid > .row > .wide.column,
.ui.stackable.grid > .wide.column {
padding-right: 0;
padding-left: 0;
}
}
.ui.one.column.grid > .column:not(.row, :first-of-type) {
padding-top: 0;
}
/**
* Wishlist Card
*/
.wishlist .ui.card {
--padding: 0.91666667em;
--buttonsHeight: calc((.92857143rem + 0.78571429em * 2) * 2 + 0.25em + 0.75em * 2 - 4px);
--buttonsHeight: calc((.92857143rem + 0.78571429em * 2) * 2 + 0.25em + 0.75em);
}
.wishlist .ui.card:focus-within {
z-index: calc(var(--dimmerZIndex) + 2);
@ -85,7 +105,7 @@ figure {
.wishlist .ui.fluid.card.stretch {
height: 100%;
}
.wishlist .ui.fluid.card.stretch::before {
.wishlist:not(.one).column .ui.fluid.card.stretch::before {
position: absolute;
right: 0;
left: 0;
@ -100,7 +120,7 @@ figure {
background-image: linear-gradient(0deg, rgba(255, 255, 255, 1) 0.75em, rgba(255, 255, 255, 0.9) 45%, rgba(255, 255, 255, 0) 100%);
}
@media (prefers-color-scheme: dark) {
.wishlist .ui.fluid.card.stretch::before {
.wishlist:not(.one).column .ui.fluid.card.stretch::before {
background-image: linear-gradient(0deg, rgba(17, 17, 17, 1) 0.75em, rgba(17, 17, 17, 0.9) 45%, rgba(17, 17, 17, 0) 100%);
}
}
@ -108,6 +128,12 @@ figure {
height: 100%;
}
.ui.card.horizontal,
.ui.horizontal.cards > .card {
flex-wrap: nowrap;
width: auto;
}
/** Image */
.wishlist .ui.card > .image {
--hoverHeight: calc(1em + 3 * var(--padding));
@ -116,11 +142,14 @@ figure {
.wishlist .ui.card > .image > :is(svg, img.preview) {
display: block;
height: 100%;
}
.wishlist:not(.one).column .ui.card > .image > :is(svg, img.preview) {
height: var(--hoverHeight);
}
@media (hover: hover) {
.wishlist .ui.card > .image > :is(svg, img.preview) {
height: var(--wishPreviewHeight);
.wishlist:not(.one).column .ui.card > .image > :is(svg, img.preview) {
height: max(var(--hoverHeight), var(--wishPreviewHeight));
}
}
@ -158,7 +187,7 @@ figure {
0.2s linear opacity;
}
}
.wishlist .ui.card:hover > .image > svg {
.wishlist:not(.one).column .ui.card:hover > .image > svg {
height: calc(var(--hoverHeight) - 5px);
padding: 0 !important;
opacity: 0;
@ -187,11 +216,20 @@ figure {
}
}
.wishlist .ui.card:hover > .image > img.preview {
.wishlist:not(.one).column .ui.card:hover > .image > img.preview {
height: var(--hoverHeight);
}
}
.ui.card.horizontal > .image,
.ui.horizontal.cards > .card > .image {
--sizeCardY: calc(1.28571429em * 1.28571429 + 2em + 3px);
--sizeFaviconX: calc(1.25em + var(--padding) * 2);
width: min(var(--sizeFaviconX), var(--sizeCardY));
min-height: var(--sizeCardY);
}
/** Provider */
.wishlist .ui.card > .image,
.wishlist .ui.card > .image > span.provider {
@ -282,9 +320,10 @@ figure {
/** Content */
.wishlist .ui.card > .content:not(.extra) {
height: 20vh;
overflow: auto;
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 0.5em;
}
@media (hover: hover) {
@ -296,37 +335,52 @@ figure {
}
}
.wishlist .ui.card > .content:not(.extra) {
.wishlist:not(.one).column .ui.card > .content:not(.extra) {
height: calc(var(--wishPreviewHeight) * 1.25);
overflow: hidden;
}
.ui:not(.one).column .ui.card:hover > .content:not(.extra) {
.wishlist:not(.one).column .ui.card:hover > .content:not(.extra) {
margin-bottom: var(--buttonsHeight);
overflow: auto;
}
}
.wishlist .ui.card > .content > .header {
flex-shrink: 0;
max-height: calc(2 * 1.28571429em);
overflow: hidden;
}
.wishlist .ui.card > .content > .description {
margin-top: 0;
overflow: auto;
}
/** Buttons */
.wishlist .ui.card > .extra.buttons {
.wishlist .ui.card > .extra.buttons,
.wishlist .ui.card > .content > .extra.buttons {
position: relative;
display: flex;
justify-content: flex-start;
align-items: center;
flex-direction: column;
gap: 0.25em;
width: 100%;
padding-top: 0;
background-color: inherit;
z-index: 2;
}
.wishlist .ui.card > .content > .extra.buttons {
flex-direction: row;
}
@media (hover: hover) {
.wishlist .ui.card > .extra.buttons {
.wishlist:not(.one).column .ui.card > .extra.buttons {
position: absolute;
top: unset;
right: 0;
@ -338,23 +392,25 @@ figure {
margin-bottom: 0;
}
@media (prefers-reduced-motion: no-preference) {
.wishlist .ui.card > .extra.buttons {
.wishlist:not(.one).column .ui.card > .extra.buttons {
transition:
0.2s ease opacity,
0.2s ease bottom;
}
}
.wishlist .ui.card:hover > .extra.buttons {
.wishlist:not(.one).column .ui.card:hover > .extra.buttons {
opacity: 1;
bottom: 0;
}
}
.wishlist .ui.card > .extra.buttons > .button {
flex: 1 1 auto;
.wishlist .ui.card > .extra.buttons > .button,
.wishlist .ui.card > .content > .extra.buttons > .button {
width: 100%;
margin: 0;
flex: 1 1 auto;
}
/** Overlay */

View file

@ -33,6 +33,16 @@
color: rgba(0, 0, 0, .8);
}
.ui.buttons:not(.basic):not(.inverted) > .button:not(.basic):not(.inverted) {
box-shadow: 0 0 0 2px #dcddde inset;
}
.ui.buttons .button {
margin: 0 0 0 -2px;
}
.ui.buttons .button:first-child {
margin-left: 0;
}
/** Primary */
.ui.primary.button,
.ui.primary.buttons .button {

View file

@ -18,10 +18,11 @@ $(function() {
*/
/** API */
$.fn.api.settings.api = {
'get wishlists' : '/?page=api&module=wishlists',
'delete wishlist' : '/?page=api&module=wishlists',
'update wish status' : '/?page=api&module=wishes',
'delete wish' : '/?page=api&module=wishes',
'get wishlists' : '/?page=api&module=wishlists&api_token={apitoken}&style={style}',
'get wishlists with priority' : '/?page=api&module=wishlists&api_token={apitoken}&style={style}&wishlist_id={wishlistid}&priority={priority}',
'delete wishlist' : '/?page=api&module=wishlists',
'update wish status' : '/?page=api&module=wishes',
'delete wish' : '/?page=api&module=wishes',
};
/** Default callbacks */

View file

@ -7,53 +7,61 @@ $(function () {
.dropdown({
match : 'text',
fullTextSearch : true,
onChange : function() {
$(this).addClass('disabled loading');
})
.dropdown('set selected', -1)
.api({
'action' : 'get wishlists with priority',
'urlData' : {
'apitoken' : api.token,
},
beforeSend : function (settings) {
settings.urlData.style = $('input[name="style"]').val();
settings.urlData.priority = $('.ui.dropdown.filter.priority').dropdown('get value');
var wishlist_id;
/** Wishlist ID */
var wistlist_cards_data = $('.wishlist-cards').attr('data-wishlist')
var dropdown_wishlists = $('.dropdown.wishlists');
if (dropdown_wishlists.length) {
wishlist_id = $('.dropdown.wishlists').dropdown('get value');
settings.urlData.wishlistid = $('.dropdown.wishlists').dropdown('get value');
}
if (typeof wistlist_cards_data !== 'undefined') {
wishlist_id = wistlist_cards_data;
settings.urlData.wishlistid = wistlist_cards_data;
}
/** */
if (!Number.isInteger(parseInt(wishlist_id))) {
$(this).removeClass('disabled loading');
return settings;
},
onSuccess : function (response, dropdown_wishlists, xhr) {
var html = response.results ? response.results : '';
return false;
}
const parameter = new URLSearchParams(
{
'api_token' : api.token,
'module' : 'wishlists',
'page' : 'api',
'priority' : $(this).dropdown('get value'),
'wishlist' : wishlist_id,
}
);
fetch('/?' + parameter, {
method : 'GET',
})
.then(handleFetchError)
.then(handleFetchResponse)
.then(function(response) {
var html = response.results ? response.results : '';
$('.wishlist-cards').html(html);
$('.ui.dropdown.options').dropdown();
})
.finally(() => {
$(this).removeClass('disabled loading');
});
$('.wishlist-cards').html(html);
$('.ui.dropdown.options').dropdown();
}
});
/**
* Style
*/
$('.buttons.view .button[value]').on('click', function() {
$('input[name="style"]').val( $(this).val() );
$('.buttons.view .button[value]').removeClass('active');
$(this).addClass('active');
$('.ui.dropdown.filter.priority').api('query');
});
if ($('.ui.dropdown.wishlists').length === 0) {
const orientationIsPortrait = window.matchMedia('(orientation: portrait)');
if (orientationIsPortrait.matches) {
$('.buttons.view .button[value="list"]').trigger('click');
} else {
$('.buttons.view .button[value="grid"]').trigger('click');
}
}
});

View file

@ -1,62 +1,82 @@
$(function () {
/**
* General
*/
var wishlist = {
'id' : $_GET.id
};
/**
* Progress
*/
var progress = $('.ui.progress');
progress.progress({
onSuccess : function() {
$(this).slideUp();
}
});
/**
* Get Wishlists
*/
var wishlists = [];
var progress = $('.ui.progress');
progress.progress({
onSuccess : function() {
$(this).slideUp();
}
});
var wishlists = [];
$('.ui.dropdown.wishlists').dropdown();
$('.ui.dropdown.wishlists')
.dropdown()
.api({
'action' : 'get wishlists',
'urlData' : {
'apitoken' : api.token,
},
beforeSend : function (settings) {
settings.urlData.style = $('input[name="style"]').val();
function wishlistsRefresh() {
$('.ui.dropdown.wishlists').api({
action : 'get wishlists',
method : 'GET',
on : 'now',
data : {
'api_token' : api.token,
},
onSuccess : function (response, element, xhr) {
wishlists = response.results;
return settings;
},
onSuccess : function (response, dropdown_wishlists, xhr) {
/** Set wishlists */
wishlists = response.results;
element.dropdown({
values : wishlists
})
dropdown_wishlists.dropdown({
values : wishlists
})
if (wishlist.id) {
element.dropdown('set selected', wishlist.id);
} else {
if (wishlists[0]) {
element.dropdown('set selected', wishlists[0].value);
}
}
/** Open add wish modal */
if ($_GET.wish_add) {
$('.button.wishlist-wish-add').trigger('click');
/** Select current/active wishlist */
if (wishlist.id) {
dropdown_wishlists.dropdown('set selected', wishlist.id);
} else {
if (wishlists.length >= 1) {
dropdown_wishlists.dropdown('set selected', Object.values(wishlists)[0]);
}
}
});
}
wishlistsRefresh();
/** Open add wish modal */
if ($_GET.wish_add) {
$('.button.wishlist-wish-add').trigger('click');
}
/** Filter wishes */
const orientationIsPortrait = window.matchMedia('(orientation: portrait)');
if (orientationIsPortrait.matches) {
$('.buttons.view .button[value="list"]').trigger('click');
} else {
$('.buttons.view .button[value="grid"]').trigger('click');
}
}
})
.api('query');
$(document).on('change', '.ui.dropdown.wishlists', function () {
var wishlistValue = $('.ui.dropdown.wishlists').dropdown('get value');
var wishlistIndex = $('.ui.dropdown.wishlists select').prop('selectedIndex') - 1;
return;
if (wishlistValue) {
wishlist.id = wishlistValue;
var wishlist_id = $('.ui.dropdown.wishlists').dropdown('get value');
$('.wishlist-share').attr('href', '/?page=wishlist&hash=' + wishlists[wishlistIndex].hash);
if (wishlist_id) {
wishlist.id = wishlist_id;
$('.wishlist-share').attr('href', '/?page=wishlist&hash=' + wishlists[wishlist_id].hash);
$('.button.wishlist-wish-add').removeClass('disabled');
$('.button.wishlist-share').removeClass('disabled');
@ -64,7 +84,7 @@ $(function () {
$('.wishlist-delete').removeClass('disabled');
/** Update URL */
urlParams.set('id', wishlistValue);
urlParams.set('id', wishlist_id);
const params_url = new URLSearchParams(
{
@ -85,7 +105,8 @@ $(function () {
$('.ui.dropdown.filter.priority')
.dropdown('restore default value')
.dropdown('restore default text');
.dropdown('restore default text')
.dropdown('set selected', -1);
});
} else {
$('.button.wishlist-wish-add').addClass('disabled');
@ -97,8 +118,8 @@ $(function () {
/**
* Cards
*/
if (wishlistIndex >= 0) {
$('.wishlist-cards').html(wishlists[wishlistIndex].cards);
if (wishlist.id) {
$('.wishlist-cards').html(wishlists[wishlist.id].cards);
} else {
$('.wishlist-cards').html('');
}
@ -152,8 +173,8 @@ $(function () {
return;
}
var wishlistIndex = $('.ui.dropdown.wishlists select').prop('selectedIndex') - 1;
var wishlist_user = wishlists[wishlistIndex].user;
var wishlist_id = $('.ui.dropdown.wishlists').dropdown('get value') - 1;
var wishlist_user = wishlists[wishlist_id].user;
card.addClass('loading');
card.attr('data-cache', 'false');
@ -230,7 +251,7 @@ $(function () {
.then(handleFetchError)
.then(handleFetchResponse)
.then(function(response) {
wishlistsRefresh();
$('.ui.dropdown.wishlists').api('query');
modalRename.modal('hide');
@ -276,9 +297,9 @@ $(function () {
* Delete Wishlist
*/
$(document).on('click', '.options .wishlist-delete', function () {
var wishlistValue = $('.ui.dropdown.wishlists').dropdown('get value');
var wishlist_id = $('.ui.dropdown.wishlists').dropdown('get value');
if (wishlistValue) {
if (wishlist_id) {
var modalDefault = $('.ui.modal.default');
modalDefault
@ -306,7 +327,7 @@ $(function () {
data: {
'api_token' : api.token,
'wishlistID' : wishlistValue
'wishlistID' : wishlist_id
},
on: 'now',
onSuccess: function (response, wishlists) {
@ -321,7 +342,7 @@ $(function () {
modalDefault.modal('hide');
setTimeout(() => {
wishlistsRefresh();
$('.ui.dropdown.wishlists').api('query');
}, 200);
}
});
@ -494,7 +515,7 @@ $(function () {
modalDefault.modal('hide');
setTimeout(() => {
wishlistsRefresh();
$('.ui.dropdown.wishlists').api('query');
}, 800);
},
});
@ -600,7 +621,7 @@ $(function () {
$('body').toast({ message: text.toast_wish_create });
wishlistsRefresh();
$('.ui.dropdown.wishlists').api('query');
})
.finally(() => {
formWishlistCreate.removeClass('loading');
@ -727,7 +748,7 @@ $(function () {
$('body').toast({ message: text.toast_wish_update });
wishlistsRefresh();
$('.ui.dropdown.wishlists').api('query');
modalAddOrEdit.modal('hide');
})
@ -759,7 +780,7 @@ $(function () {
$('body').toast({ message: text.toast_wish_update });
wishlistsRefresh();
$('.ui.dropdown.wishlists').api('query');
modalAddOrEdit.modal('hide');
})

View file

@ -60,6 +60,7 @@ class Wish
public ?int $priority;
public bool $is_purchasable;
public ?string $status;
public string $style = 'grid';
/** Product */
public ?float $price;
@ -123,8 +124,7 @@ class Wish
$userCard->getLocale(),
\NumberFormatter::CURRENCY
);
$userIsCurrent = isset($_SESSION['user']->id) && $_SESSION['user']->id === $userCard->id;
$userIsCurrent = isset($_SESSION['user']->id) && $_SESSION['user']->id === $userCard->id;
/**
* Card
@ -134,156 +134,84 @@ class Wish
} else {
$generateCache = 'false';
}
?>
<div class="ui blurring dimmable fluid card stretch"
data-id="<?= $this->id ?>"
data-cache="<?= $generateCache ?>"
>
<div class="ui inverted dimmer">
<div class="content">
<div class="center">
<div class="ui icon header">
<i class="history icon"></i>
<div class="content">
<?= __('Wish temporarily fulfilled') ?>
<div class="sub header">
<?php
printf(
/** TRANSLATORS: %s: Duration (i. e. 30 minutes) */
__('If this wish is a product, confirm the order was successful and mark it as fulfilled here. If you do not confirm this wish as fulfilled, it will become available again to others after %s.'),
sprintf(
/** TRANSLATORS: %d Amount of minutes */
'<strong>' . __('%d minutes') . '</strong>',
self::STATUS_TEMPORARY_MINUTES
)
)
?>
switch ($this->style) {
case 'list':
?>
<div class="ui horizontal card">
<?= $this->getCardImage() ?>
<div class="content">
<?= $this->getCardPriority() ?>
<?= $this->getCardContentHeader() ?>
<?php if ($this->price) { ?>
<?= $this->getCardContentMeta($numberFormatter->format($this->price)) ?>
<?php } ?>
<?= $this->getCardContentDescription() ?>
<?= $this->getCardButtons($userIsCurrent) ?>
</div>
</div>
<?php
break;
default:
?>
<div class="ui blurring dimmable fluid card stretch"
data-id="<?= $this->id ?>"
data-cache="<?= $generateCache ?>"
>
<div class="ui inverted dimmer">
<div class="content">
<div class="center">
<div class="ui icon header">
<i class="history icon"></i>
<div class="content">
<?= __('Wish temporarily fulfilled') ?>
<div class="sub header">
<?php
printf(
/** TRANSLATORS: %s: Duration (i. e. 30 minutes) */
__('If this wish is a product, confirm the order was successful and mark it as fulfilled here. If you do not confirm this wish as fulfilled, it will become available again to others after %s.'),
sprintf(
/** TRANSLATORS: %d Amount of minutes */
'<strong>' . __('%d minutes') . '</strong>',
self::STATUS_TEMPORARY_MINUTES
)
)
?>
</div>
</div>
</div>
<button class="ui positive labeled icon button confirm">
<i class="check double icon"></i>
<?= __('Confirm') ?>
</button>
</div>
</div>
<button class="ui positive labeled icon button confirm">
<i class="check double icon"></i>
<?= __('Confirm') ?>
</button>
</div>
</div>
</div>
<div class="image">
<?php if ($this->priority && isset(self::$priorities[$this->priority])) { ?>
<div class="ui small <?= self::$priorities[$this->priority]['color'] ?> right ribbon label">
<?= self::$priorities[$this->priority]['name'] ?>
</div>
<?php } ?>
<?= $this->getCardImage() ?>
<?php if ($this->image) { ?>
<?php if ('svg' === pathinfo($this->image, PATHINFO_EXTENSION)) { ?>
<?php if (file_exists(ROOT . $this->image)) { ?>
<?= file_get_contents(ROOT . $this->image) ?>
<?php } else { ?>
<?= file_get_contents($this->image) ?>
<div class="content">
<?php if ($this->title) { ?>
<?= $this->getCardContentHeader() ?>
<?php } ?>
<?php } else { ?>
<img class="preview" src="<?= $this->image ?>" loading="lazy" />
<?php } ?>
<?php } else { ?>
<?= file_get_contents(ROOT . self::NO_IMAGE) ?>
<?php } ?>
<?php if (isset($this->info->favicon) && $this->info->favicon) { ?>
<img class="favicon" src="<?= $this->info->favicon ?>" loading="lazy" />
<?php } ?>
<?php if (isset($this->info->providerName) && $this->info->providerName) { ?>
<span class="provider"><?= $this->info->providerName ?></span>
<?php } ?>
</div>
<div class="content">
<?php if ($this->title) { ?>
<div class="header">
<?php if ($this->url) { ?>
<a href="<?= $this->url ?>" target="_blank"><?= $this->title ?></a>
<?php } else { ?>
<?= $this->title ?>
<?php if ($this->price) { ?>
<?= $this->getCardContentMeta($numberFormatter->format($this->price)) ?>
<?php } ?>
</div>
<?php } ?>
<?php if ($this->price) { ?>
<div class="meta">
<span class="date"><?= $numberFormatter->format($this->price) ?></span>
<?= $this->getCardContentDescription() ?>
</div>
<?php } ?>
<div class="description">
<?php if ($this->description) { ?>
<?= $this->description ?>
<?php } elseif ($this->url && !$this->title) { ?>
<a href="<?= $this->url ?>" target="_blank"><?= $this->url ?></a>
<?php } ?>
<?= $this->getCardButtons($userIsCurrent) ?>
</div>
</div>
<div class="extra content buttons">
<?php if (!$userIsCurrent) { ?>
<a class="ui small primary labeled icon button fulfil"
title="<?= __('Fulfil wish') ?>"
>
<i class="gift icon"></i>
<?= __('Fulfil wish') ?>
</a>
<?php } ?>
<?php if ($this->url) { ?>
<a class="ui small labeled icon button<?= $userIsCurrent ? ' primary' : '' ?>"
href="<?= $this->url ?>" target="_blank"
title="<?= __('Visit') ?>"
>
<i class="external icon"></i>
<?= __('Visit') ?>
</a>
<?php } else { ?>
<a class="ui small labeled icon disabled button<?= $userIsCurrent ? ' primary' : '' ?>"
title="<?= __('Visit') ?>"
>
<i class="external icon"></i>
<?= __('Visit') ?>
</a>
<?php } ?>
<?php if ($userIsCurrent) { ?>
<div class="ui small labeled icon top left pointing dropdown button options"
title="<?= __('Options') ?>"
>
<i class="cog icon"></i>
<span class="text"><?= __('Options') ?></span>
<div class="menu">
<button class="item wish-fulfilled">
<i class="check icon"></i>
<?= __('Mark as fulfilled') ?>
</button>
<button class="item wish-edit" data-id="<?= $this->id ?>">
<i class="pen icon"></i>
<?= __('Edit') ?>
</button>
<button class="item wish-delete">
<i class="trash icon"></i>
<?= __('Delete') ?>
</button>
</div>
</div>
<?php } ?>
</div>
</div>
<?php
<?php
break;
}
$html = ob_get_clean();
@ -303,4 +231,178 @@ class Wish
return $title;
}
private function getCardImage(): string
{
ob_start();
?>
<div class="image">
<?php if ('grid' === $this->style) { ?>
<?= $this->getCardPriority() ?>
<?php } ?>
<?php if ($this->image) { ?>
<?php if ('svg' === pathinfo($this->image, PATHINFO_EXTENSION)) { ?>
<?php if (file_exists(ROOT . $this->image)) { ?>
<?= file_get_contents(ROOT . $this->image) ?>
<?php } else { ?>
<?= file_get_contents($this->image) ?>
<?php } ?>
<?php } else { ?>
<img class="preview" src="<?= $this->image ?>" loading="lazy" />
<?php } ?>
<?php } else { ?>
<?= file_get_contents(ROOT . self::NO_IMAGE) ?>
<?php } ?>
<?php if (isset($this->info->favicon) && $this->info->favicon) { ?>
<img class="favicon" src="<?= $this->info->favicon ?>" loading="lazy" />
<?php } ?>
<?php if (isset($this->info->providerName) && $this->info->providerName) { ?>
<span class="provider"><?= $this->info->providerName ?></span>
<?php } ?>
</div>
<?php
$image = ob_get_clean();
return $image;
}
private function getCardContentHeader(): string
{
ob_start();
?>
<div class="header">
<?php if ($this->url) { ?>
<a href="<?= $this->url ?>" target="_blank"><?= $this->title ?></a>
<?php } else { ?>
<?= $this->title ?>
<?php } ?>
</div>
<?php
$content_header = ob_get_clean();
return $content_header;
}
private function getCardContentMeta(string $price): string
{
ob_start();
?>
<div class="meta">
<span class="date"><?= $price ?></span>
</div>
<?php
$content_meta = ob_get_clean();
return $content_meta;
}
private function getCardContentDescription(): string
{
ob_start();
?>
<?php if ($this->description) { ?>
<div class="description">
<?= $this->description ?>
</div>
<?php } elseif ($this->url && !$this->title) { ?>
<div class="description">
<a href="<?= $this->url ?>" target="_blank"><?= $this->url ?></a>
</div>
<?php } ?>
<?php
$content_description = ob_get_clean();
return $content_description;
}
private function getCardPriority(): string
{
switch ($this->style) {
case 'list':
$direction = 'left';
break;
default:
$direction = 'right';
break;
}
ob_start();
?>
<?php if ($this->priority && isset(self::$priorities[$this->priority])) { ?>
<div class="ui small <?= self::$priorities[$this->priority]['color'] ?> <?= $direction ?> ribbon label">
<?= self::$priorities[$this->priority]['name'] ?>
</div>
<?php } ?>
<?php
$priority = ob_get_clean();
return $priority;
}
private function getCardButtons(bool $userIsCurrent): string
{
ob_start();
?>
<div class="extra content buttons">
<?php if (!$userIsCurrent) { ?>
<a class="ui small primary labeled icon button fulfil"
title="<?= __('Fulfil wish') ?>"
>
<i class="gift icon"></i>
<?= __('Fulfil wish') ?>
</a>
<?php } ?>
<?php if ($this->url) { ?>
<a class="ui small labeled icon button<?= $userIsCurrent ? ' primary' : '' ?>"
href="<?= $this->url ?>" target="_blank"
title="<?= __('Visit') ?>"
>
<i class="external icon"></i>
<?= __('Visit') ?>
</a>
<?php } else { ?>
<a class="ui small labeled icon disabled button<?= $userIsCurrent ? ' primary' : '' ?>"
title="<?= __('Visit') ?>"
>
<i class="external icon"></i>
<?= __('Visit') ?>
</a>
<?php } ?>
<?php if ($userIsCurrent) { ?>
<div class="ui small labeled icon top left pointing dropdown button options"
title="<?= __('Options') ?>"
>
<i class="cog icon"></i>
<span class="text"><?= __('Options') ?></span>
<div class="menu">
<button class="item wish-fulfilled">
<i class="check icon"></i>
<?= __('Mark as fulfilled') ?>
</button>
<button class="item wish-edit" data-id="<?= $this->id ?>">
<i class="pen icon"></i>
<?= __('Edit') ?>
</button>
<button class="item wish-delete">
<i class="trash icon"></i>
<?= __('Delete') ?>
</button>
</div>
</div>
<?php } ?>
</div>
<?php
$buttons = ob_get_clean();
return $buttons;
}
}

View file

@ -83,7 +83,7 @@ class Wishlist
return $this->wishes;
}
public function getCards($options = array()): string
public function getCards(array $options = array()): string
{
ob_start();
@ -94,24 +94,56 @@ class Wishlist
$this->wishes = $this->getWishes($options);
}
$style = isset($options['style']) ? $options['style'] : 'grid';
/**
* Cards
*/
?>
<div class="ui three column doubling stackable grid wishlist">
<?php if (!empty($this->wishes)) { ?>
<?php foreach ($this->wishes as $wish) { ?>
<div class="column">
<?= $wish->getCard($this->user) ?>
</div>
<?php } ?>
<?php } else { ?>
<div class="sixteen wide column">
<?= Page::info(__('This wishlist seems to be empty.'), __('Empty')); ?>
switch ($style) {
case 'list':
?>
<div class="ui one column doubling stackable grid wishlist">
<?php if (!empty($this->wishes)) { ?>
<?php foreach ($this->wishes as $wish) { ?>
<div class="column">
<?php
$wish->style = $style;
echo $wish->getCard($this->user);
?>
</div>
<?php } ?>
<?php } else { ?>
<div class="sixteen wide column">
<?= Page::info(__('This wishlist seems to be empty.'), __('Empty')); ?>
</div>
<?php } ?>
</div>
<?php } ?>
</div>
<?php
<?php
break;
default:
?>
<div class="ui three column doubling stackable grid wishlist">
<?php if (!empty($this->wishes)) { ?>
<?php foreach ($this->wishes as $wish) { ?>
<div class="column">
<?php
$wish->style = $style;
echo $wish->getCard($this->user);
?>
</div>
<?php } ?>
<?php } else { ?>
<div class="sixteen wide column">
<?= Page::info(__('This wishlist seems to be empty.'), __('Empty')); ?>
</div>
<?php } ?>
</div>
<?php
break;
}
$html = ob_get_clean();

View file

@ -70,7 +70,7 @@ $page->navigation();
<li>
<?php
/** TRANSLATORS: Changelog: Roadmap */
echo __('Compact/list view for wishes');
echo __('Verify wishes are still available when attempting to fulfill them. Alternatively, a heartbeat which checks if all the wishes are still unfulfilled.');
?>
</li>
<li>
@ -99,6 +99,12 @@ $page->navigation();
echo __('A roadmap in the changelog.');
?>
</li>
<li>
<?php
/** TRANSLATORS: Changelog: Roadmap */
echo __('Compact/list view for wishes');
?>
</li>
</ul>
<h3 class="ui header"><?= __('Improved') ?></h3>

View file

@ -56,6 +56,12 @@ $scriptPart = '/src/assets/js/parts/wishlist-filter.js';
</div>
</div>
<input type="hidden" name="style" value="grid" />
<div class="ui icon buttons view">
<button class="ui button" value="grid"><i class="grip horizontal icon"></i></button>
<button class="ui button" value="list"><i class="grip lines icon"></i></button>
</div>
</div>
</div>
</div>

View file

@ -73,6 +73,7 @@ $page->navigation();
<div class="wishlist-cards" data-wishlist="<?= $wishlist->id ?>">
<?php
/*
echo $wishlist->getCards(
array(
'WHERE' => '`wishlist` = ' . $wishlist->id . '
@ -84,6 +85,7 @@ $page->navigation();
AND (`status` != "' . Wish::STATUS_UNAVAILABLE . '" OR `status` IS NULL)'
)
);
*/
?>
</div>