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; break;
case 'GET': 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']); $wishlist = new Wishlist($_GET['wishlist_id']);
$options = array(); $options = array(
'style' => $_GET['style'],
);
$where = array( $where = array(
'wishlist' => '`wishlist` = ' . $wishlist->id, 'wishlist' => '`wishlist` = ' . $wishlist->id,
'priority' => '`priority` = ' . $_GET['priority'], 'priority' => '`priority` = ' . $_GET['priority'],
@ -113,9 +115,7 @@ switch ($_SERVER['REQUEST_METHOD']) {
$where['priority'] = '`priority` IS NULL'; $where['priority'] = '`priority` IS NULL';
} }
$options = array( $options['WHERE'] = '(' . implode(') AND (', $where) . ')';
'WHERE' => '(' . implode(') AND (', $where) . ')',
);
$response['results'] = $wishlist->getCards($options); $response['results'] = $wishlist->getCards($options);
} elseif (isset($_GET['userid']) || isset($_SESSION['user']->id)) { } 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']; $user = isset($_GET['userid']) ? User::getFromID($_GET['userid']) : $_SESSION['user'];
$wishlists = $user->getWishlists(); $wishlists = array();
$wishlists = array_map( $options = array(
function ($dataWishlist) { 'style' => $_GET['style'],
/**
* 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
); );
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; $response['results'] = $wishlists;
} }
break; break;

View file

@ -1,6 +1,6 @@
:root { :root {
--lineHeight: 1.4285; --lineHeight: 1.4285;
--wishPreviewHeight: min(30vh, 192px); --wishPreviewHeight: 192px;
--dimmerZIndex: 100; --dimmerZIndex: 100;
} }
@ -71,12 +71,32 @@ figure {
margin: 0; 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 Card
*/ */
.wishlist .ui.card { .wishlist .ui.card {
--padding: 0.91666667em; --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 { .wishlist .ui.card:focus-within {
z-index: calc(var(--dimmerZIndex) + 2); z-index: calc(var(--dimmerZIndex) + 2);
@ -85,7 +105,7 @@ figure {
.wishlist .ui.fluid.card.stretch { .wishlist .ui.fluid.card.stretch {
height: 100%; height: 100%;
} }
.wishlist .ui.fluid.card.stretch::before { .wishlist:not(.one).column .ui.fluid.card.stretch::before {
position: absolute; position: absolute;
right: 0; right: 0;
left: 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%); 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) { @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%); 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%; height: 100%;
} }
.ui.card.horizontal,
.ui.horizontal.cards > .card {
flex-wrap: nowrap;
width: auto;
}
/** Image */ /** Image */
.wishlist .ui.card > .image { .wishlist .ui.card > .image {
--hoverHeight: calc(1em + 3 * var(--padding)); --hoverHeight: calc(1em + 3 * var(--padding));
@ -116,11 +142,14 @@ figure {
.wishlist .ui.card > .image > :is(svg, img.preview) { .wishlist .ui.card > .image > :is(svg, img.preview) {
display: block; display: block;
height: 100%;
}
.wishlist:not(.one).column .ui.card > .image > :is(svg, img.preview) {
height: var(--hoverHeight); height: var(--hoverHeight);
} }
@media (hover: hover) { @media (hover: hover) {
.wishlist .ui.card > .image > :is(svg, img.preview) { .wishlist:not(.one).column .ui.card > .image > :is(svg, img.preview) {
height: var(--wishPreviewHeight); height: max(var(--hoverHeight), var(--wishPreviewHeight));
} }
} }
@ -158,7 +187,7 @@ figure {
0.2s linear opacity; 0.2s linear opacity;
} }
} }
.wishlist .ui.card:hover > .image > svg { .wishlist:not(.one).column .ui.card:hover > .image > svg {
height: calc(var(--hoverHeight) - 5px); height: calc(var(--hoverHeight) - 5px);
padding: 0 !important; padding: 0 !important;
opacity: 0; 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); 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 */ /** Provider */
.wishlist .ui.card > .image, .wishlist .ui.card > .image,
.wishlist .ui.card > .image > span.provider { .wishlist .ui.card > .image > span.provider {
@ -282,9 +320,10 @@ figure {
/** Content */ /** Content */
.wishlist .ui.card > .content:not(.extra) { .wishlist .ui.card > .content:not(.extra) {
height: 20vh; display: flex;
flex-direction: column;
overflow: auto; align-items: flex-start;
gap: 0.5em;
} }
@media (hover: hover) { @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; 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); margin-bottom: var(--buttonsHeight);
overflow: auto;
} }
} }
.wishlist .ui.card > .content > .header { .wishlist .ui.card > .content > .header {
flex-shrink: 0;
max-height: calc(2 * 1.28571429em); max-height: calc(2 * 1.28571429em);
overflow: hidden; overflow: hidden;
} }
.wishlist .ui.card > .content > .description {
margin-top: 0;
overflow: auto;
}
/** Buttons */ /** Buttons */
.wishlist .ui.card > .extra.buttons { .wishlist .ui.card > .extra.buttons,
.wishlist .ui.card > .content > .extra.buttons {
position: relative; position: relative;
display: flex; display: flex;
justify-content: flex-start;
align-items: center; align-items: center;
flex-direction: column; flex-direction: column;
gap: 0.25em; gap: 0.25em;
width: 100%;
padding-top: 0;
background-color: inherit; background-color: inherit;
z-index: 2; z-index: 2;
} }
.wishlist .ui.card > .content > .extra.buttons {
flex-direction: row;
}
@media (hover: hover) { @media (hover: hover) {
.wishlist .ui.card > .extra.buttons { .wishlist:not(.one).column .ui.card > .extra.buttons {
position: absolute; position: absolute;
top: unset; top: unset;
right: 0; right: 0;
@ -338,23 +392,25 @@ figure {
margin-bottom: 0; margin-bottom: 0;
} }
@media (prefers-reduced-motion: no-preference) { @media (prefers-reduced-motion: no-preference) {
.wishlist .ui.card > .extra.buttons { .wishlist:not(.one).column .ui.card > .extra.buttons {
transition: transition:
0.2s ease opacity, 0.2s ease opacity,
0.2s ease bottom; 0.2s ease bottom;
} }
} }
.wishlist .ui.card:hover > .extra.buttons { .wishlist:not(.one).column .ui.card:hover > .extra.buttons {
opacity: 1; opacity: 1;
bottom: 0; bottom: 0;
} }
} }
.wishlist .ui.card > .extra.buttons > .button { .wishlist .ui.card > .extra.buttons > .button,
flex: 1 1 auto; .wishlist .ui.card > .content > .extra.buttons > .button {
width: 100%; width: 100%;
margin: 0; margin: 0;
flex: 1 1 auto;
} }
/** Overlay */ /** Overlay */

View file

@ -33,6 +33,16 @@
color: rgba(0, 0, 0, .8); 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 */ /** Primary */
.ui.primary.button, .ui.primary.button,
.ui.primary.buttons .button { .ui.primary.buttons .button {

View file

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

View file

@ -7,53 +7,61 @@ $(function () {
.dropdown({ .dropdown({
match : 'text', match : 'text',
fullTextSearch : true, 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 wistlist_cards_data = $('.wishlist-cards').attr('data-wishlist')
var dropdown_wishlists = $('.dropdown.wishlists'); var dropdown_wishlists = $('.dropdown.wishlists');
if (dropdown_wishlists.length) { 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') { if (typeof wistlist_cards_data !== 'undefined') {
wishlist_id = wistlist_cards_data; settings.urlData.wishlistid = wistlist_cards_data;
} }
/** */
if (!Number.isInteger(parseInt(wishlist_id))) { return settings;
$(this).removeClass('disabled loading'); },
onSuccess : function (response, dropdown_wishlists, xhr) {
var html = response.results ? response.results : '';
return false; $('.wishlist-cards').html(html);
} $('.ui.dropdown.options').dropdown();
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');
});
} }
}); });
/**
* 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 () { $(function () {
/**
* General
*/
var wishlist = { var wishlist = {
'id' : $_GET.id 'id' : $_GET.id
}; };
/**
* Progress
*/
var progress = $('.ui.progress');
progress.progress({
onSuccess : function() {
$(this).slideUp();
}
});
/** /**
* Get Wishlists * Get Wishlists
*/ */
var wishlists = []; var wishlists = [];
var progress = $('.ui.progress');
progress.progress({
onSuccess : function() {
$(this).slideUp();
}
});
$('.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() { return settings;
$('.ui.dropdown.wishlists').api({ },
action : 'get wishlists', onSuccess : function (response, dropdown_wishlists, xhr) {
method : 'GET', /** Set wishlists */
on : 'now', wishlists = response.results;
data : {
'api_token' : api.token,
},
onSuccess : function (response, element, xhr) {
wishlists = response.results;
element.dropdown({ dropdown_wishlists.dropdown({
values : wishlists values : wishlists
}) })
if (wishlist.id) { /** Select current/active wishlist */
element.dropdown('set selected', wishlist.id); if (wishlist.id) {
} else { dropdown_wishlists.dropdown('set selected', wishlist.id);
if (wishlists[0]) { } else {
element.dropdown('set selected', wishlists[0].value); if (wishlists.length >= 1) {
} dropdown_wishlists.dropdown('set selected', Object.values(wishlists)[0]);
}
/** Open add wish modal */
if ($_GET.wish_add) {
$('.button.wishlist-wish-add').trigger('click');
} }
} }
});
}
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 () { $(document).on('change', '.ui.dropdown.wishlists', function () {
var wishlistValue = $('.ui.dropdown.wishlists').dropdown('get value'); return;
var wishlistIndex = $('.ui.dropdown.wishlists select').prop('selectedIndex') - 1;
if (wishlistValue) { var wishlist_id = $('.ui.dropdown.wishlists').dropdown('get value');
wishlist.id = wishlistValue;
$('.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-wish-add').removeClass('disabled');
$('.button.wishlist-share').removeClass('disabled'); $('.button.wishlist-share').removeClass('disabled');
@ -64,7 +84,7 @@ $(function () {
$('.wishlist-delete').removeClass('disabled'); $('.wishlist-delete').removeClass('disabled');
/** Update URL */ /** Update URL */
urlParams.set('id', wishlistValue); urlParams.set('id', wishlist_id);
const params_url = new URLSearchParams( const params_url = new URLSearchParams(
{ {
@ -85,7 +105,8 @@ $(function () {
$('.ui.dropdown.filter.priority') $('.ui.dropdown.filter.priority')
.dropdown('restore default value') .dropdown('restore default value')
.dropdown('restore default text'); .dropdown('restore default text')
.dropdown('set selected', -1);
}); });
} else { } else {
$('.button.wishlist-wish-add').addClass('disabled'); $('.button.wishlist-wish-add').addClass('disabled');
@ -97,8 +118,8 @@ $(function () {
/** /**
* Cards * Cards
*/ */
if (wishlistIndex >= 0) { if (wishlist.id) {
$('.wishlist-cards').html(wishlists[wishlistIndex].cards); $('.wishlist-cards').html(wishlists[wishlist.id].cards);
} else { } else {
$('.wishlist-cards').html(''); $('.wishlist-cards').html('');
} }
@ -152,8 +173,8 @@ $(function () {
return; return;
} }
var wishlistIndex = $('.ui.dropdown.wishlists select').prop('selectedIndex') - 1; var wishlist_id = $('.ui.dropdown.wishlists').dropdown('get value') - 1;
var wishlist_user = wishlists[wishlistIndex].user; var wishlist_user = wishlists[wishlist_id].user;
card.addClass('loading'); card.addClass('loading');
card.attr('data-cache', 'false'); card.attr('data-cache', 'false');
@ -230,7 +251,7 @@ $(function () {
.then(handleFetchError) .then(handleFetchError)
.then(handleFetchResponse) .then(handleFetchResponse)
.then(function(response) { .then(function(response) {
wishlistsRefresh(); $('.ui.dropdown.wishlists').api('query');
modalRename.modal('hide'); modalRename.modal('hide');
@ -276,9 +297,9 @@ $(function () {
* Delete Wishlist * Delete Wishlist
*/ */
$(document).on('click', '.options .wishlist-delete', function () { $(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'); var modalDefault = $('.ui.modal.default');
modalDefault modalDefault
@ -306,7 +327,7 @@ $(function () {
data: { data: {
'api_token' : api.token, 'api_token' : api.token,
'wishlistID' : wishlistValue 'wishlistID' : wishlist_id
}, },
on: 'now', on: 'now',
onSuccess: function (response, wishlists) { onSuccess: function (response, wishlists) {
@ -321,7 +342,7 @@ $(function () {
modalDefault.modal('hide'); modalDefault.modal('hide');
setTimeout(() => { setTimeout(() => {
wishlistsRefresh(); $('.ui.dropdown.wishlists').api('query');
}, 200); }, 200);
} }
}); });
@ -494,7 +515,7 @@ $(function () {
modalDefault.modal('hide'); modalDefault.modal('hide');
setTimeout(() => { setTimeout(() => {
wishlistsRefresh(); $('.ui.dropdown.wishlists').api('query');
}, 800); }, 800);
}, },
}); });
@ -600,7 +621,7 @@ $(function () {
$('body').toast({ message: text.toast_wish_create }); $('body').toast({ message: text.toast_wish_create });
wishlistsRefresh(); $('.ui.dropdown.wishlists').api('query');
}) })
.finally(() => { .finally(() => {
formWishlistCreate.removeClass('loading'); formWishlistCreate.removeClass('loading');
@ -727,7 +748,7 @@ $(function () {
$('body').toast({ message: text.toast_wish_update }); $('body').toast({ message: text.toast_wish_update });
wishlistsRefresh(); $('.ui.dropdown.wishlists').api('query');
modalAddOrEdit.modal('hide'); modalAddOrEdit.modal('hide');
}) })
@ -759,7 +780,7 @@ $(function () {
$('body').toast({ message: text.toast_wish_update }); $('body').toast({ message: text.toast_wish_update });
wishlistsRefresh(); $('.ui.dropdown.wishlists').api('query');
modalAddOrEdit.modal('hide'); modalAddOrEdit.modal('hide');
}) })

View file

@ -60,6 +60,7 @@ class Wish
public ?int $priority; public ?int $priority;
public bool $is_purchasable; public bool $is_purchasable;
public ?string $status; public ?string $status;
public string $style = 'grid';
/** Product */ /** Product */
public ?float $price; public ?float $price;
@ -123,8 +124,7 @@ class Wish
$userCard->getLocale(), $userCard->getLocale(),
\NumberFormatter::CURRENCY \NumberFormatter::CURRENCY
); );
$userIsCurrent = isset($_SESSION['user']->id) && $_SESSION['user']->id === $userCard->id;
$userIsCurrent = isset($_SESSION['user']->id) && $_SESSION['user']->id === $userCard->id;
/** /**
* Card * Card
@ -134,156 +134,84 @@ class Wish
} else { } else {
$generateCache = 'false'; $generateCache = 'false';
} }
?>
<div class="ui blurring dimmable fluid card stretch" switch ($this->style) {
data-id="<?= $this->id ?>" case 'list':
data-cache="<?= $generateCache ?>" ?>
> <div class="ui horizontal card">
<div class="ui inverted dimmer"> <?= $this->getCardImage() ?>
<div class="content">
<div class="center"> <div class="content">
<div class="ui icon header"> <?= $this->getCardPriority() ?>
<i class="history icon"></i> <?= $this->getCardContentHeader() ?>
<div class="content">
<?= __('Wish temporarily fulfilled') ?> <?php if ($this->price) { ?>
<div class="sub header"> <?= $this->getCardContentMeta($numberFormatter->format($this->price)) ?>
<?php <?php } ?>
printf(
/** TRANSLATORS: %s: Duration (i. e. 30 minutes) */ <?= $this->getCardContentDescription() ?>
__('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.'), <?= $this->getCardButtons($userIsCurrent) ?>
sprintf( </div>
/** TRANSLATORS: %d Amount of minutes */ </div>
'<strong>' . __('%d minutes') . '</strong>', <?php
self::STATUS_TEMPORARY_MINUTES 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> </div>
<button class="ui positive labeled icon button confirm">
<i class="check double icon"></i>
<?= __('Confirm') ?>
</button>
</div> </div>
</div> </div>
<button class="ui positive labeled icon button confirm">
<i class="check double icon"></i>
<?= __('Confirm') ?>
</button>
</div> </div>
</div>
</div>
<div class="image"> <?= $this->getCardImage() ?>
<?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 } ?>
<?php if ($this->image) { ?> <div class="content">
<?php if ('svg' === pathinfo($this->image, PATHINFO_EXTENSION)) { ?> <?php if ($this->title) { ?>
<?php if (file_exists(ROOT . $this->image)) { ?> <?= $this->getCardContentHeader() ?>
<?= file_get_contents(ROOT . $this->image) ?>
<?php } else { ?>
<?= file_get_contents($this->image) ?>
<?php } ?> <?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) { ?> <?php if ($this->price) { ?>
<img class="favicon" src="<?= $this->info->favicon ?>" loading="lazy" /> <?= $this->getCardContentMeta($numberFormatter->format($this->price)) ?>
<?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 } ?> <?php } ?>
</div>
<?php } ?>
<?php if ($this->price) { ?> <?= $this->getCardContentDescription() ?>
<div class="meta">
<span class="date"><?= $numberFormatter->format($this->price) ?></span>
</div> </div>
<?php } ?>
<div class="description"> <?= $this->getCardButtons($userIsCurrent) ?>
<?php if ($this->description) { ?>
<?= $this->description ?>
<?php } elseif ($this->url && !$this->title) { ?>
<a href="<?= $this->url ?>" target="_blank"><?= $this->url ?></a>
<?php } ?>
</div> </div>
</div> <?php
break;
<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
$html = ob_get_clean(); $html = ob_get_clean();
@ -303,4 +231,178 @@ class Wish
return $title; 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; return $this->wishes;
} }
public function getCards($options = array()): string public function getCards(array $options = array()): string
{ {
ob_start(); ob_start();
@ -94,24 +94,56 @@ class Wishlist
$this->wishes = $this->getWishes($options); $this->wishes = $this->getWishes($options);
} }
$style = isset($options['style']) ? $options['style'] : 'grid';
/** /**
* Cards * Cards
*/ */
?> switch ($style) {
<div class="ui three column doubling stackable grid wishlist"> case 'list':
<?php if (!empty($this->wishes)) { ?> ?>
<?php foreach ($this->wishes as $wish) { ?> <div class="ui one column doubling stackable grid wishlist">
<div class="column"> <?php if (!empty($this->wishes)) { ?>
<?= $wish->getCard($this->user) ?> <?php foreach ($this->wishes as $wish) { ?>
</div> <div class="column">
<?php } ?> <?php
<?php } else { ?> $wish->style = $style;
<div class="sixteen wide column">
<?= Page::info(__('This wishlist seems to be empty.'), __('Empty')); ?> 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> </div>
<?php } ?> <?php
</div> break;
<?php
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(); $html = ob_get_clean();

View file

@ -70,7 +70,7 @@ $page->navigation();
<li> <li>
<?php <?php
/** TRANSLATORS: Changelog: Roadmap */ /** 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>
<li> <li>
@ -99,6 +99,12 @@ $page->navigation();
echo __('A roadmap in the changelog.'); echo __('A roadmap in the changelog.');
?> ?>
</li> </li>
<li>
<?php
/** TRANSLATORS: Changelog: Roadmap */
echo __('Compact/list view for wishes');
?>
</li>
</ul> </ul>
<h3 class="ui header"><?= __('Improved') ?></h3> <h3 class="ui header"><?= __('Improved') ?></h3>

View file

@ -56,6 +56,12 @@ $scriptPart = '/src/assets/js/parts/wishlist-filter.js';
</div> </div>
</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> </div>
</div> </div>

View file

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