Show at max only one options notification

Closes #124

Signed-off-by: Egor Savkin <es@m-labs.hk>
pull/128/head
Egor Savkin 2024-03-18 14:48:16 +08:00
parent dfe1f0ea2d
commit 6bfed3e779
4 changed files with 53 additions and 27 deletions

View File

@ -11,6 +11,13 @@ export function OptionsDialogWrapper({crate_index, card_index, first, last}) {
const card_id = useShopStore((state) => state.crates[crate_index].items[card_index].id); const card_id = useShopStore((state) => state.crates[crate_index].items[card_index].id);
const options_class = useShopStore((state) => state.crates[crate_index].items[card_index].options_class); const options_class = useShopStore((state) => state.crates[crate_index].items[card_index].options_class);
const sideMenuIsOpen = useShopStore((state) => state.sideMenuIsOpen); const sideMenuIsOpen = useShopStore((state) => state.sideMenuIsOpen);
const _notificationTimer = useShopStore((state) => state.notificationTimer);
const hideNotification = useShopStore((state) => state.hideNotification);
//const notificationCardIndex = useShopStore((state) => state.notificationCardIndex);
//const displayNotification = notificationCrateId === crate_id && notificationCardIndex === card_index;
const displayNotification = useShopStore((state) =>
state.notificationCrateId === crate_id &&
(state.notificationCardIndex === card_index || (state.crates[crate_index].items.length + (state.notificationCardIndex || -1)) === card_index));
const onOptionsUpdate = useShopStore((state) => state.updateOptions); const onOptionsUpdate = useShopStore((state) => state.updateOptions);
@ -25,6 +32,8 @@ export function OptionsDialogWrapper({crate_index, card_index, first, last}) {
first={first} first={first}
last={last} last={last}
sideMenuIsOpen={sideMenuIsOpen} sideMenuIsOpen={sideMenuIsOpen}
onHideNotification={hideNotification}
displayNotification={displayNotification}
target={{ target={{
construct: ((outvar, value) => { construct: ((outvar, value) => {
// #!options_log // #!options_log

View File

@ -3,7 +3,8 @@ import {useClickAway} from "./useClickAway";
import {ProcessOptions} from "./Options"; import {ProcessOptions} from "./Options";
import {Notification} from "./Notification"; import {Notification} from "./Notification";
export function DialogPopup({options, data, target, id, big, first, last, options_class, sideMenuIsOpen}) { export function DialogPopup({options, data, target, id, big, first, last, options_class,
sideMenuIsOpen, displayNotification, onHideNotification}) {
const [show, setShow] = useState(false); const [show, setShow] = useState(false);
const ref = useClickAway((e) => { const ref = useClickAway((e) => {
if (e.type === "mousedown") // ignore touchstart if (e.type === "mousedown") // ignore touchstart
@ -22,8 +23,11 @@ export function DialogPopup({options, data, target, id, big, first, last, option
id={"processed_options_notification" + id} id={"processed_options_notification" + id}
tip="Customization options available" tip="Customization options available"
sideMenuIsOpen={sideMenuIsOpen} sideMenuIsOpen={sideMenuIsOpen}
show={displayNotification}
onHide={onHideNotification}
content={ content={
<img className="alert-info" src={show ? "/images/shop/icon-close.svg" : "/images/shop/icon-customize.svg"} <img className="alert-info"
src={show ? "/images/shop/icon-close.svg" : "/images/shop/icon-customize.svg"}
onClick={handleClick}/> onClick={handleClick}/>
} }
/> />

View File

@ -1,30 +1,18 @@
import {OverlayTrigger, Tooltip} from "react-bootstrap"; import {OverlayTrigger, Tooltip} from "react-bootstrap";
import React, {useEffect, useState} from "react"; import React from "react";
export function Notification({id, tip, content, sideMenuIsOpen}) {
const [show, setShow] = useState(false);
useEffect(() => {
setTimeout(() => {
setShow(true)
}, 100);
setTimeout(() => {
setShow(false)
}, 5000);
}, []);
export function Notification({id, tip, content, sideMenuIsOpen, show, onHide}) {
return ( return (
<OverlayTrigger <OverlayTrigger
placement="top" placement="top"
trigger={["click", "hover"]} trigger={["click", "hover"]}
style={{display: 'inline'}} style={{display: 'inline'}}
show={show} show={show}
onToggle={() => setShow(false)} overlay={props => <Tooltip id={id} {...props}>{tip}</Tooltip>}
overlay={props => <Tooltip id={id} {...props}>{tip}</Tooltip>} rootClose={!sideMenuIsOpen}
rootClose={!sideMenuIsOpen} onToggle={onHide}
> >
{content} {content}
</OverlayTrigger> </OverlayTrigger>
) )
} }

View File

@ -29,6 +29,28 @@ const useCatalog = ((set, get) => ({
cardIndexById: card_id => get().cards_list.findIndex((element) => (card_id === element)) cardIndexById: card_id => get().cards_list.findIndex((element) => (card_id === element))
})); }));
const useOptionsNotification = ((set, get) => ({
notificationCrateId: null,
notificationCardIndex: null,
notificationTimer: null,
_showNotification: (crate_id, card_index) => set(state => ({
notificationCrateId: crate_id,
notificationCardIndex: card_index,
notificationTimer: setTimeout(() => {
state.hideNotification()
}, 5000)
})),
showNotification: (crate_id, card_index) => {
get().hideNotification()
setTimeout(() => get()._showNotification(crate_id, card_index), 100);
},
hideNotification: () => set(state => ({
notificationCrateId: null,
notificationCardIndex: null,
notificationTimer: (state.notificationTimer && clearTimeout(state.notificationTimer)) || null,
}))
}));
const useSearch = ((set, get) => ({ const useSearch = ((set, get) => ({
search_index: Array.from(Object.values(shared_data.items) search_index: Array.from(Object.values(shared_data.items)
.map((card, _) => ( .map((card, _) => (
@ -182,6 +204,7 @@ const useImportJSON = ((set, get) => ({
get().fillExtCrateData(crate.id); get().fillExtCrateData(crate.id);
}); });
get()._updateTotalOrderPrice(); get()._updateTotalOrderPrice();
get().showNotification(get().active_crate, null);
}, },
updateImportDescription: (new_description) => set(state => ({ updateImportDescription: (new_description) => set(state => ({
importValue: { importValue: {
@ -532,6 +555,7 @@ const useCart = ((set, get) => ({
get().noDestinationWarning(); get().noDestinationWarning();
return {}; return {};
} }
get().showNotification(dest, index_to);
get()._addCardFromCatalog(dest, index_from, index_to) get()._addCardFromCatalog(dest, index_from, index_to)
get().fillExtData(dest); get().fillExtData(dest);
get().fillWarnings(dest); get().fillWarnings(dest);
@ -583,6 +607,7 @@ const useCart = ((set, get) => ({
export const useShopStore = createWithEqualityFn((...params) => ({ export const useShopStore = createWithEqualityFn((...params) => ({
...useOptionsNotification(...params),
...useCatalog(...params), ...useCatalog(...params),
...useSearch(...params), ...useSearch(...params),
...useCrateModes(...params), ...useCrateModes(...params),