const ELEMENT_NODE = 1 const TEXT_NODE = 3 const IS_NON_DIMENSIONAL = /acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i function merge(...objects) { return Object.assign({}, ...objects) } function isValidNodeType(obj) { return obj != null && typeof obj !== "boolean" } function isSameNode(a, b) { return a.tag === b.tag && a.key === b.key } function isSameNodeType(a, b) { if (a.type !== b.type) { return false } if (a.type === TEXT_NODE && a.text !== b.text) { return false } if (a.tag !== b.tag) { return false } return true } function createClass(value) { if (typeof value === "string") { return value } let output = "" if (Array.isArray(value) && value.length > 0) { for (let i = 0, len = value.length, tmp; i < len; i++) { if ((tmp = createClass(value[i])) !== "") { output += (output && " ") + tmp } } } else { for (const cls in value) { if (value[cls]) { output += (output && " ") + cls } } } return output } function createKeyToIndexMap(children, beginIndex, endIndex) { const map = {} for (let i = beginIndex; i <= endIndex; ++i) { const child = children[i] const key = child && child.key if (key != null) { map[key] = i } } return map } function createVNode(tag, props, children, node = null) { return { type: ELEMENT_NODE, tag, props, children, key: props.key || null, node, } } function createTextVNode(text, node = null) { return { type: TEXT_NODE, text: String(text), node, } } function normalizeChildren(children) { return children.flat(Infinity).reduce((vnodes, vnode) => { if (isValidNodeType(vnode)) { const type = typeof vnode if (type === "string" || type === "number") { vnode = createTextVNode(vnode) } vnodes.push(vnode) } return vnodes }, []) } function recycle(node) { if (node.nodeType === 3) { return createTextVNode(node.data, node) } if (node.nodeType === 1) { return createVNode( node.nodeName.toLowerCase(), Array.from(node.attributes).reduce((map, attr) => { const name = attr.name, value = attr.value if (name !== "style") { map[name] = value } if (name === "key") { node.removeAttribute("key") } return map }, {}), Array.from(node.childNodes).map(recycle), node, ) } } function createElement(vnode, isSvg) { let node if (vnode.type === TEXT_NODE) { node = document.createTextNode(vnode.text) } else { const { tag, props, children } = vnode const length = children.length isSvg = isSvg || tag === "svg" node = isSvg ? document.createElementNS("http://www.w3.org/2000/svg", tag) : document.createElement(tag) Object.keys(props).forEach((name) => patchProperty(node, name, null, props[name], isSvg), ) if (length === 1) { node.appendChild(createElement(children[0], isSvg)) } else if (length > 1) { node.appendChild( children.reduce( (frag, vchild) => frag.appendChild(createElement(vchild, isSvg)) && frag, document.createDocumentFragment(), ), ) } } vnode.node = node return node } function setStyle(element, name, value) { if (name.startsWith("--")) { element.style.setProperty(name, value == null ? "" : value) } else if (value == null) { element.style[name] = "" } else if (typeof value != "number" || IS_NON_DIMENSIONAL.test(name)) { element.style[name] = value } else { element.style[name] = value + "px" } } function patchProperty(element, name, prevVal, nextVal, isSvg) { if (name === "key" || name === "children") { return } if (name === "style") { if (typeof nextVal === "string") { element.style.cssText = nextVal } else { if (typeof prevVal === "string") { element.style.cssText = prevVal = "" } for (const key in merge(nextVal, prevVal)) { setStyle(element, key, nextVal == null ? "" : nextVal[key]) } } } else if ( name.startsWith("on") && (typeof prevVal === "function" || typeof nextVal === "function") ) { name = name.toLowerCase() in element ? name.toLowerCase().slice(2) : name.slice(2) if (nextVal) { element.addEventListener(name, nextVal) } if (prevVal) { element.removeEventListener(name, prevVal) } } else if (typeof nextVal !== "function") { if (nextVal != null && (name === "class" || name === "className")) { nextVal = createClass(nextVal) } if (!isSvg && name === "class") { name = "className" } if ( !isSvg && name !== "width" && name !== "height" && name !== "href" && name !== "list" && name !== "form" && name !== "tabIndex" && name !== "download" && name !== "rowSpan" && name !== "colSpan" && name !== "role" && name in element ) { try { element[name] = nextVal == null ? "" : nextVal return } catch (e) {} // eslint-disable-line no-empty } if (nextVal != null && (nextVal !== false || name.indexOf("-") != -1)) { element.setAttribute(name, nextVal) } else { element.removeAttribute(name) } } } function patchChildren(parent, prevChildren, nextChildren, isSvg) { let prevStartIndex = 0 let prevEndIndex = prevChildren.length - 1 let prevStartChild = prevChildren[0] let prevEndChild = prevChildren[prevEndIndex] let nextStartIndex = 0 let nextEndIndex = nextChildren.length - 1 let nextStartChild = nextChildren[0] let nextEndChild = nextChildren[nextEndIndex] let prevKeyToIdx while (prevStartIndex <= prevEndIndex && nextStartIndex <= nextEndIndex) { if (!prevStartChild) { prevStartChild = prevChildren[++prevStartIndex] } else if (!prevEndChild) { prevEndChild = prevChildren[--prevEndIndex] } else if (isSameNode(prevStartChild, nextStartChild)) { patchElement(parent, prevStartChild, nextStartChild, isSvg) prevStartChild = prevChildren[++prevStartIndex] nextStartChild = nextChildren[++nextStartIndex] } else if (isSameNode(prevEndChild, nextEndChild)) { patchElement(parent, prevEndChild, nextEndChild, isSvg) prevEndChild = prevChildren[--prevEndIndex] nextEndChild = nextChildren[--nextEndIndex] } else if (isSameNode(prevStartChild, nextEndChild)) { patchElement(parent, prevStartChild, nextEndChild, isSvg) parent.insertBefore( prevStartChild.node, prevEndChild.node.nextSibling, ) prevStartChild = prevChildren[++prevStartIndex] nextEndChild = nextChildren[--nextEndIndex] } else if (isSameNode(prevEndChild, nextStartChild)) { patchElement(parent, prevEndChild, nextStartChild, isSvg) parent.insertBefore(prevEndChild.node, prevStartChild.node) prevEndChild = prevChildren[--prevEndIndex] nextStartChild = nextChildren[++nextStartIndex] } else { if (!prevKeyToIdx) { prevKeyToIdx = createKeyToIndexMap( prevChildren, prevStartIndex, prevEndIndex, ) } const key = nextStartChild.key const prevIndex = key ? prevKeyToIdx[key] : null if (prevIndex == null) { parent.insertBefore( createElement(nextStartChild, isSvg), prevStartChild.node, ) nextStartChild = nextChildren[++nextStartIndex] } else { let prevChildToMove = prevChildren[prevIndex] patchElement(parent, prevChildToMove, nextStartChild, isSvg) prevChildren[prevIndex] = undefined parent.insertBefore(prevChildToMove.node, prevStartChild.node) nextStartChild = nextChildren[++nextStartIndex] } } } if (prevStartIndex > prevEndIndex) { const subsequentElement = nextChildren[nextEndIndex + 1] ? nextChildren[nextEndIndex + 1].node : null for (let i = nextStartIndex; i <= nextEndIndex; i++) { parent.insertBefore( createElement(nextChildren[i], isSvg), subsequentElement, ) } } else if (nextStartIndex > nextEndIndex) { for (let i = prevStartIndex; i <= prevEndIndex; i++) { const child = prevChildren[i] if (child && child.node) { parent.removeChild(child.node) } } } return nextChildren } function patchElement(parent, prevVNode, nextVNode, isSvg) { if (prevVNode === nextVNode) { if (prevVNode == null) { return null } return prevVNode.node } if (prevVNode == null) { return parent.appendChild(createElement(nextVNode, isSvg)) } let element = prevVNode.node if (nextVNode == null) { return parent.removeChild(element) && null } if (prevVNode.type === TEXT_NODE && nextVNode.type === TEXT_NODE) { if (prevVNode.text !== nextVNode.text) { element.data = nextVNode.text } } else if (!isSameNodeType(nextVNode, prevVNode)) { const nextElement = createElement(nextVNode, isSvg) parent.replaceChild(nextElement, element) element = nextElement } else { isSvg = isSvg || nextVNode.tag === "svg" const activeElement = document.activeElement const prevVProps = prevVNode.props const nextVProps = nextVNode.props for (const name in merge(nextVProps, prevVProps)) { if ( (name === "value" || name === "selected" || name === "checked" ? element[name] : prevVProps[name]) !== nextVProps[name] ) { patchProperty( element, name, prevVProps[name], nextVProps[name], isSvg, ) } } patchChildren(element, prevVNode.children, nextVNode.children, isSvg) if (activeElement !== document.body) { activeElement.focus() } } nextVNode.node = element return element } function render(parent, nextVNode) { let prevVNode = parent._vnode || null if (!prevVNode && parent.childNodes.length > 0) { prevVNode = Array.from(parent.childNodes).map(recycle) } const prevIsArray = Array.isArray(prevVNode) const nextIsArray = Array.isArray(nextVNode) parent._vnode = nextVNode if (prevIsArray || nextIsArray) { const prevVChildren = (prevIsArray ? prevVNode : [prevVNode]).filter( isValidNodeType, ) const nextVChildren = (nextIsArray ? nextVNode : [nextVNode]).filter( isValidNodeType, ) const root = patchChildren(parent, prevVChildren, nextVChildren) return root.length === 0 ? null : root.length === 1 ? root[0].node : root.map((vnode) => vnode.node) } return patchElement(parent, prevVNode, nextVNode) } function h(tag, props, ...children) { if ( !props || props.type === ELEMENT_NODE || props.type === TEXT_NODE || typeof props.concat === "function" ) { children = [].concat(props || [], ...children) props = null } props = props || {} children = normalizeChildren(children) if (typeof tag === "function") { return tag({ children, ...props }) } return createVNode(tag, props, children) } function text(str) { return createTextVNode(str) } let CSS_STATEMENT_RE = /([^{};]*)([;{}])/g let LINE_BREAK_RE = /(\r\n|\r|\n)+/g let TAB_RE = /\t/g let EXTRA_SPACES_RE = /\s{2,}/g let COMMENTS_RE = /\/\*[\W\w]*?\*\//g let TRAILING_SEPARATOR_SPACES_RE = /\s*([:;{}])\s*/g let UNNECESSARY_SEPARATOR_RE = /\};+/g let TRAILING_SEPARATORS_RE = /([^:;{}])}/g function normalize(css) { throw "dead" return css .replace(LINE_BREAK_RE, " ") .replace(TAB_RE, " ") .replace(EXTRA_SPACES_RE, " ") .replace(COMMENTS_RE, "") .trim() .replace(TRAILING_SEPARATOR_SPACES_RE, "$1") .replace(UNNECESSARY_SEPARATOR_RE, "}") .replace(TRAILING_SEPARATORS_RE, "$1;}") } function walk(css, callback) { throw "dead" css = normalize(css) CSS_STATEMENT_RE.lastIndex = 0 for (let m; (m = CSS_STATEMENT_RE.exec(css)) != null; ) { callback(m[1], m[2]) } } function compileTaggedTemplate(strings, values, callback) { throw "dead" return strings.raw.reduce( (acc, str, i) => acc + callback(values[i - 1]) + str, ) } let stylesheet let CLASS_PREFIX = "s" let SELECTOR_GROUP_RE = /([\s\S]+,[\s\S]+)/m function parseNestedCSS(css) { throw "dead" let ast = [{ children: [] }] let depth = 0 walk(css, (style, char) => { if (char == "{") { ast[++depth] = { selector: style, rules: "", children: [], } } else if (char == "}") { ast[depth].rules += style ast[--depth].children.push(ast.pop()) } else if (char == ";") { ast[depth].rules += style + char } }) return ast[0].children } function buildCSS(ast, parent) { throw "dead" return ast.reduce((css, block) => { let selector = block.selector.trim() if (selector[0] === "@") { css += selector + "{" if (block.children.length > 0) { css += buildCSS(block.children, parent) + "}" } } else { if (parent && selector[0] === "&") { selector = parent + selector.substring(1).replace(SELECTOR_GROUP_RE, ":is($1)") } else if (parent) { selector = parent + " " + selector.replace(SELECTOR_GROUP_RE, ":is($1)") } else { selector = selector.replace(SELECTOR_GROUP_RE, ":is($1)") } css += selector + "{" + block.rules + "}" if (block.children.length > 0) { css += buildCSS(block.children, selector) } } return css }, "") } function compileCSS(css) { throw "dead" return buildCSS(parseNestedCSS(css)) } function resolveValue(value) { throw "dead" if (typeof value === "function") { return resolveValue(value()) } if (value && value.nodeType === 1 && value.nodeName === "STYLE") { return value.textContent } return value } function appendCSS(css) { if (!stylesheet) { stylesheet = document.createElement("style") document.head.appendChild(stylesheet) } stylesheet.textContent += css + "\n\n" } function style(strings, ...values) { throw "dead" let styles = compileTaggedTemplate(strings, values, resolveValue) let className = CLASS_PREFIX + uuid() appendCSS(compileCSS(`.${className} { ${styles} }`)) return className } function css(strings, ...values) { let styles = compileTaggedTemplate(strings, values, resolveValue) appendCSS(compileCSS(styles)) } let Div = "div" let Span = "span" let Img = "img" let StyleId = 0 function CreateStyle(table) { StyleId += 1 let className = "s" + StyleId let styles = "" for (let key in table) { let value = table[key] styles = styles.concat("\t", key, ": ", value, ";", "\n") } appendCSS(`.${className} {\n${styles}}`) return className } function AddStyleTo(className, pseudo, table) { let styles = "" for (let key in table) { let value = table[key] styles = styles.concat("\t", key, ": ", value, ";", "\n") } appendCSS(`.${className}:${pseudo} {\n${styles}}`) return className } function AddStyleToBaseClass(className, pseudo, table) { let styles = "" for (let key in table) { let value = table[key] styles = styles.concat("\t", key, ": ", value, ";", "\n") } appendCSS(`${className}:${pseudo} {\n${styles}}`) return className } function AddStyle(className, table) { let styles = "" for (let key in table) { let value = table[key] styles = styles.concat("\t", key, ": ", value, ";", "\n") } appendCSS(`${className} {\n${styles}}`) return className } AddStyle("body", { "-webkit-user-select": "none", "background-color": "var(--block-bg-color)", "color-scheme": "var(--tg-color-scheme)", "color": "var(--text-color)", "cursor": "default", "font-family": "var(--default-font)", "font-size": "13px", "font-weight": "400", "line-height": "16px", // "padding": "20px", "min-width": "100%", "padding": "0", "user-select": "none", "width": "1px", "display": "flex", "justify-content": "center", "align-items": "center", "margin-top": "20px", }) AddStyle(":root", { "--default-font": '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"', "--accent-text-color": "var(--tg-theme-accent-text-color)", "--animation": "0.15s ease", "--bg-color": "var(--tg-theme-bg-color)", "--bottom-bar-bg-color": "var(--tg-theme-bottom-bar-bg-color)", "--button-color": "var(--tg-theme-button-color)", "--button-text-color": "var(--tg-theme-button-text-color)", "--destructive-text-color": "var(--tg-theme-destructive-text-color)", "--header-bg-color": "var(--tg-theme-header-bg-color)", "--hint-color": "var(--tg-theme-hint-color)", "--link-color": "var(--tg-theme-link-color)", "--page-animation-duration": "0.3s", "--page-animation": "var(--page-animation-duration) ease", "--page-hint-color": "#83878a", "--placeholder-color": "#999da1", "--ripple-duration": "0.45s", "--ripple-end-duration": "0.3s", "--secondary-bg-color": "var(--tg-theme-secondary-bg-color)", "--section-bg-color": "var(--tg-theme-section-bg-color)", "--section-header-text-color": "var(--tg-theme-section-header-text-color)", "--section-separator-color": "var(--tg-theme-section-separator-color)", "--status-height": "48px", "--subtitle-text-color": "var(--tg-theme-subtitle-text-color)", "--text-color": "var(--tg-theme-text-color)", }) AddStyle("*", { "-webkit-tap-highlight-color": "transparent", }) AddStyle("button", { "cursor": "pointer", }) let StyleStoreItem = CreateStyle({ "background-color": "var(--secondary-bg-color)", "border-radius": "7px", "box-sizing": "border-box", "overflow": "hidden", "padding": "8px", "position": "relative", "text-align": "center", "width": "calc(100% / 2.05)", }) let StyleStoreBlock = CreateStyle({ "-webkit-box-shadow": "0 0.5px rgba(0, 0, 0, 0.07)", "background-color": "var(--block-bg-color)", "box-shadow": "0 0.5px rgba(0, 0, 0, 0.07)", }) let StyleStoreItems = CreateStyle({ "align-content": "flex-start", "display": "flex", "flex-wrap": "wrap", "justify-content": "space-between", "margin": "10px", "max-width": "480px", "overflow": "hidden", "row-gap": "8px", "transition": "max-height var(--page-animation), opacity var(--page-animation)", // "width": "fit-content", }) let StyleStoreCategory = CreateStyle({ "background-color": "var(--secondary-bg-color)", "border-radius": "7px", "box-sizing": "border-box", "height": "182px", "overflow": "hidden", "padding": "8px", "position": "relative", "text-align": "center", "transition": "all var(--animation)", "width": "calc(100% / 2.05)", }) let StyleSelected = CreateStyle({ "color": "#ff0000", }) function CssCombine() { return Array.from(arguments).join(" ") } let StyleStoreCategorySelected = CssCombine(StyleStoreCategory, StyleSelected) AddStyleTo(StyleStoreCategory, "hover", { "transform": "scale(1.05)", }) AddStyleTo(StyleStoreCategory, "active", { "transform": "scale(1.05)", }) let StyleStoreItemPhoto = CreateStyle({ "height": "150px", "position": "relative", }) let StyleStoreItemImage = CreateStyle({ "bottom": "0", "display": "inline-block", "height": "100%", "left": "0", "margin": "0 auto", "position": "relative", "right": "0", "top": "0", "vertical-align": "top", "width": "100%", // 'position': 'absolute', // 'width': '146px', }) let StyleStoreItemBadge = CreateStyle({ "border-radius": "4px", "border": "none", "box-sizing": "border-box", "color": "#fff", "display": "inline-block", "font-family": "var(--default-font)", "font-size": "13px", "font-weight": "500", "left": "5px", "line-height": "14px", "outline": "none", "padding": "2px 4px", "position": "absolute", "text-transform": "uppercase", "top": "5px", "transform": "rotate(-12deg)", }) let StyleStoreItemLabel = CreateStyle({ "align-items": "flex-start", "display": "flex", "flex-direction": "column", "font-size": "15px", "gap": "6px", "margin": "0 1px", "overflow": "hidden", "text-overflow": "ellipsis", "white-space": "nowrap", }) let StyleStoreItemTitle = CreateStyle({}) let StyleStoreItemPrice = CreateStyle({ "font-weight": "700", "white-space": "nowrap", }) let StyleStoreItemButtons = CreateStyle({ "display": "flex", "margin": "8px auto 0", "position": "relative", "transition": "all var(--animation)", }) let StyleStoreItemCounter = CreateStyle({ "animation": "var(--animation) both", "font-size": "20px", "height": "32px", "line-height": "32px", "margin": "12px", "min-width": "32px", "pointer-events": "none", "position": "absolute", "right": "0", "text-align": "center", "top": "0", "transform": "scale3d(0, 0, 1)", "vertical-align": "middle", "z-index": "3", }) let StyleNumberInput = CreateStyle({ "border-radius": "0", "border": "none", "box-sizing": "border-box", "color": "var(--text-color)", "cursor": "auto", "display": "block", "font-family": "var(--default-font)", "font-size": "17px", "height": "32px", "line-height": "21px", "outline": "none", "padding": "0px 10px", "resize": "none", "user-select": "auto", "width": "48px", }) let StyleLoadingContainer = CreateStyle({ "-webkit-transform": "translate(-50%, -50%)", "left": "50%", "position": "absolute", "top": "50%", "transform": "translate(-50%, -50%)", }) let StyleItemTitle = CreateStyle({ "font-size": "18px", "font-weight": "700", "line-height": "18px", "overflow": "hidden", "padding": "3px 0", "white-space": "nowrap", "width": "200px", }) let StyleStatusWrap = CreateStyle({ "left": "0", "position": "fixed", "right": "0", "top": "0", "transform": "translateY(var(--tg-viewport-height, 100vh))", "z-index": "1", }) AddStyle(".cafe-order-header-wrap", { "align-items": "center", "display": "flex", "padding": "21px 20px 14px", }) AddStyle(".cafe-order-header", { "flex-grow": "1", "font-size": "17px", "line-height": "21px", "margin": "0", "padding": "0", "text-transform": "uppercase", }) AddStyle(".cafe-item-buy-button", { "background-color": "var(--accent-color)", "position": "absolute !important", "right": "0", "top": "0", "transition": "width var(--animation)", "width": "80px", }) AddStyle(".cafe-item-incr-button", { "transition": "all var(--animation)", "width": "100%", "position": "absolute !important", "right": "0", "top": "0", }) AddStyle(".cafe-item-decr-button", { "background-color": "#e64d44", "pointer-events": "none", "transform": "scale3d(0.9, 0.9, 1)", "transition": "transform var(--animation), visibility var(--animation)", "visibility": "hidden", }) AddStyle(".cafe-status", { "position": "fixed", "bottom": "0", "left": "0", "right": "0", "display": "block", "width": "100%", "padding": "8px 20px", "display": "flex", "justify-content": "center", "align-items": "center", "border-radius": "0", "background-color": "#e64d44", "box-shadow": "0 var(--status-height) #e64d44", "color": "#fff", "height": "var(--status-height)", "transition": "transform var(--animation), visibility var(--animation)", "transform": "translateY(var(--status-height))", "box-sizing": "border-box", "pointer-events": "none", "visibility": "hidden", "z-index": "11", }) // .cafe-item-counter let StyleItemCounter = CreateStyle({ "display": "inline-block", "font-family": "var(--default-font)", "font-weight": "700", "font-size": "13px", "line-height": "18px", "height": "30px", "border-radius": "7px", "box-sizing": "border-box", "background-color": "var(--link-color)", "color": "#fff", "outline": "none", "border": "none", "white-space": "nowrap", "text-overflow": "ellipsis", "overflow": "hidden", "display": "flex", "justify-content": "center", "align-items": "center", }) // css` // .cafe-item-incr-button:active { // transform: scale(1.1); // } // ` // css` // .selected .cafe-item-incr-button { // width: 48%; // } // ` // css` // .cafe-item-decr-button { // position: relative; // width: 48%; // } // ` // css` // .selected .cafe-item-decr-button { // pointer-events: auto; // transform: scale3d(1, 1, 1); // visibility: visible; // transition: all 0.1s; // } // ` // css` // .cafe-item-decr-button:active { // transform: scale(1.1); // } // ` // css` // .cafe-item-incr-button:before, // .cafe-item-incr-button:after { // background-color: rgba(255, 255, 255, 0); // transition: background-color var(--animation); // } // ` // css` // .selected .cafe-item-incr-button:before, // .selected .cafe-item-incr-button:after { // background-color: #fff; // } // ` // css` // .cafe-item-incr-button:after { // width: 3px; // height: 14px; // } // ` // css` // .cafe-status.shown { // pointer-events: auto; // visibility: visible; // transform: translateY(0); // } // ` // css` // .cafe-order-overview { // font-family: var(--default-font); // background-color: var(--bg-color); // transition: opacity var(--page-animation); // } // ` // css` // .cafe-order-edit { // font-size: 15px; // line-height: 18px; // font-weight: 500; // color: var(--link-color); // } // ` // css` // .cafe-order-item { // display: flex; // padding: 5px 20px 5px 14px; // } // ` // css` // .cafe-order-item-label { // flex-grow: 1; // } // ` // css` // .cafe-order-item-photo { // text-align: center; // width: 50px; // height: 50px; // margin-right: 11px; // } // ` // css` // .cafe-order-item-photo .cafe-item-emoji { // font-size: 38px; // line-height: 50px; // } // ` // css` // .cafe-order-item-photo .cafe-item-lottie { // width: 40px; // margin: 4px 0; // } // ` // css` // .cafe-order-item-counter { // color: var(--link-color); // } // ` // css` // .cafe-order-item-description { // font-size: 14px; // line-height: 17px; // -webkit-font-smoothing: antialiased; // color: var(--page-hint-color); // padding: 2px 0; // } // ` // css` // .cafe-order-item-price { // font-size: 14px; // line-height: 17px; // font-weight: 500; // padding: 4px 0; // } // ` // css` // .cafe-text-field { // font-family: var(--default-font); // font-size: 17px; // line-height: 21px; // -webkit-font-smoothing: antialiased; // padding: 12px 20px 13px; // box-sizing: border-box; // display: block; // outline: none; // border: none; // border-radius: 0; // resize: none; // color: var(--text-color); // -webkit-user-select: auto; // user-select: auto; // cursor: auto; // width: 100%; // } // ` // css` // .cafe-text-field::-webkit-input-placeholder { // transition: color var(--animation); // color: var(--placeholder-color); // text-overflow: ellipsis; // } // ` // css` // .cafe-text-field::-moz-placeholder { // transition: color var(--animation); // color: var(--placeholder-color); // text-overflow: ellipsis; // } // ` // css` // .cafe-text-field:-ms-input-placeholder { // transition: color var(--animation); // color: var(--placeholder-color); // text-overflow: ellipsis; // } // ` // css` // .cafe-text-field::placeholder { // text-overflow: ellipsis; // } // ` // css` // .cafe-text-field-hint { // font-family: var(--default-font); // font-size: 14px; // line-height: 18px; // -webkit-font-smoothing: antialiased; // padding: 10px 20px 24px; // color: var(--hint-color); // } // ` let StyleButtonItemLabel = CreateStyle({ "display": "inline-block", "max-width": "100%", "overflow": "hidden", "text-overflow": "ellipsis", "vertical-align": "top", "position": "relative", "z-index": 1, }) // .cafe-item-incr-button .button-item-label AddStyleTo(StyleButtonItemLabel, { "transition": "transform var(--animation)", }) // css` // .selected .cafe-item-incr-button .button-item-label { // transform: scale3d(0.4, 0, 1); // display: none; // } // ` // css` // .cafe-switch-block { // height: 32px; // padding: 10px 20px; // display: flex; // align-items: center; // justify-content: space-between; // } // ` // css` // .cafe-switch-label { // font-family: var(--default-font); // font-size: 17px; // } // ` // css` // .switch { // position: relative; // display: inline-block; // width: 60px; // height: 32px; // } // ` // css` // .switch input { // opacity: 0; // width: 0; // height: 0; // } // ` // css` // .slider { // position: absolute; // cursor: pointer; // top: 0; // left: 0; // right: 0; // bottom: 0; // background-color: var(--tg-theme-bg-color); // -webkit-transition: 0.2s; // transition: 0.2s; // } // ` // css` // .slider:before { // position: absolute; // content: ""; // height: 24px; // width: 24px; // left: 5px; // bottom: 4px; // background-color: var(--bg-color); // -webkit-transition: 0.2s; // transition: 0.2s; // } // ` // css` // input:checked + .slider { // background-color: var(--link-color); // } // ` // css` // input:focus + .slider { // box-shadow: 0 0 1px var(--link-color); // } // ` // css` // input:checked + .slider:before { // -webkit-transform: translateX(25px); // -ms-transform: translateX(25px); // transform: translateX(25px); // } // ` // css` // @keyframes rotate-circle { // from { // transform: rotateZ(-90deg); // } // to { // transform: rotateZ(630deg); // } // } // ` // css` // @keyframes resize-circle { // from { // stroke-dashoffset: 0; // } // to { // stroke-dashoffset: 12500px; // } // } // ` // css` // @keyframes badge-incr { // from, // to { // transform: scale3d(1, 1, 1); // } // 40% { // transform: scale3d(1.2, 1.2, 1); // } // } // ` // css` // @keyframes badge-incr2 { // from, // to { // transform: scale3d(1, 1, 1); // } // 40% { // transform: scale3d(1.2, 1.2, 1); // } // } // ` // css` // @keyframes badge-decr { // from, // to { // transform: scale3d(1, 1, 1); // } // 40% { // transform: scale3d(0.8, 0.8, 1); // } // } // ` // css` // @keyframes badge-decr2 { // from, // to { // transform: scale3d(1, 1, 1); // } // 40% { // transform: scale3d(0.8, 0.8, 1); // } // } // ` // css` // @keyframes badge-show { // from { // transform: scale3d(0.5, 0.5, 1); // opacity: 0; // visibility: hidden; // } // 30% { // transform: scale3d(1.2, 1.2, 1); // } // to { // transform: scale3d(1, 1, 1); // opacity: 1; // visibility: visible; // } // } // ` // css` // @keyframes badge-hide { // from { // transform: scale3d(1, 1, 1); // opacity: 1; // visibility: visible; // } // to { // transform: scale3d(0.5, 0.5, 1); // opacity: 0; // visibility: hidden; // } // } // ` // css` // .loader { // width: 4px; // color: var(--link-color); // aspect-ratio: 1; // box-shadow: // 19px -19px 0 0px, // 38px -19px 0 0px, // 57px -19px 0 0px, // 19px 0 0 5px, // 38px 0 0 5px, // 57px 0 0 5px, // 19px 19px 0 0px, // 38px 19px 0 0px, // 57px 19px 0 0px; // transform: translateX(-38px); // animation: l26 2s infinite linear; // } // ` // css` // @keyframes l26 { // 12.5% { // box-shadow: // 19px -19px 0 0px, // 38px -19px 0 0px, // 57px -19px 0 5px, // 19px 0 0 5px, // 38px 0 0 0px, // 57px 0 0 5px, // 19px 19px 0 0px, // 38px 19px 0 0px, // 57px 19px 0 0px; // } // 25% { // box-shadow: // 19px -19px 0 5px, // 38px -19px 0 0px, // 57px -19px 0 5px, // 19px 0 0 0px, // 38px 0 0 0px, // 57px 0 0 0px, // 19px 19px 0 0px, // 38px 19px 0 5px, // 57px 19px 0 0px; // } // 50% { // box-shadow: // 19px -19px 0 5px, // 38px -19px 0 5px, // 57px -19px 0 0px, // 19px 0 0 0px, // 38px 0 0 0px, // 57px 0 0 0px, // 19px 19px 0 0px, // 38px 19px 0 0px, // 57px 19px 0 5px; // } // 62.5% { // box-shadow: // 19px -19px 0 0px, // 38px -19px 0 0px, // 57px -19px 0 0px, // 19px 0 0 5px, // 38px 0 0 0px, // 57px 0 0 0px, // 19px 19px 0 0px, // 38px 19px 0 5px, // 57px 19px 0 5px; // } // 75% { // box-shadow: // 19px -19px 0 0px, // 38px -19px 0 5px, // 57px -19px 0 0px, // 19px 0 0 0px, // 38px 0 0 0px, // 57px 0 0 5px, // 19px 19px 0 0px, // 38px 19px 0 0px, // 57px 19px 0 5px; // } // 87.5% { // box-shadow: // 19px -19px 0 0px, // 38px -19px 0 5px, // 57px -19px 0 0px, // 19px 0 0 0px, // 38px 0 0 5px, // 57px 0 0 0px, // 19px 19px 0 5px, // 38px 19px 0 0px, // 57px 19px 0 0px; // } // } // ` // css` // .gg-math-plus { // display: inline-block; // width: 2em; // height: 2em; // background-repeat: no-repeat; // background-size: 100% 100%; // background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='white' d='M19 12.998h-6v6h-2v-6H5v-2h6v-6h2v6h6z'/%3E%3C/svg%3E"); // } // ` // css` // .gg-math-minus { // display: inline-block; // width: 2em; // height: 2em; // background-repeat: no-repeat; // background-size: 100% 100%; // background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='white' d='M19 12.998H5v-2h14z'/%3E%3C/svg%3E"); // } // ` let NoImageSvg = `url('data:image/svg+xml,')` AddStyleToBaseClass(Img, "before", { "background-color": "var(--link-color)", "content": `""`, "display": "inline-block", "height": "100%", "mask-image": NoImageSvg, "mask-repeat": "no-repeat", "mask-size": "100% 100%", "opacity": "0.25", "width": "75%", }) let StyleButtonItemIcon = CreateStyle({ "display": "none", }) // css` // .selected .button-item-icon { // display: inline-block; // } // ` // css` // .checkcontainer { // display: block; // position: relative; // padding-left: 35px; // margin-bottom: 12px; // cursor: pointer; // font-size: 22px; // -webkit-user-select: none; // -moz-user-select: none; // -ms-user-select: none; // user-select: none; // } // ` // css` // .checkcontainer input { // position: absolute; // opacity: 0; // cursor: pointer; // height: 0; // width: 0; // } // ` // css` // .radiobtn { // position: absolute; // top: 0; // left: 0; // height: 25px; // width: 25px; // background-color: var(--block-bg-color); // border-radius: 50%; // } // ` // css` // .checkcontainer:hover input ~ .radiobtn { // background-color: var(--accent-color); // } // ` // css` // .checkcontainer input:checked ~ .radiobtn { // background-color: var(--link-color); // } // ` // css` // .radiobtn:after { // content: ""; // position: absolute; // display: none; // } // ` // css` // .checkcontainer input:checked ~ .radiobtn:after { // display: block; // } // ` // css` // .checkcontainer .radiobtn:after { // top: 9px; // left: 9px; // width: 8px; // height: 8px; // border-radius: 50%; // background: white; // } // ` let LoginData = {} function LoadLoginData() { let base64Decoded = window.location.search base64Decoded = base64Decoded.substring(1) let jsonDecoded try { jsonDecoded = Base64UrlDecodeString(base64Decoded) LoginData = JSON.parse(jsonDecoded) } catch (error) { return } } let StoreData = {} function LoadStoreData() { fetch("/api/store_info") .then((response) => response.json()) .then((data) => { StoreData = data Redraw() }) .catch(() => {}) } let ShoppingCard = [] let ScreenId = { Unknown: 0, Category: 1, Item: 2, } var NavigationState = { ScreenStack: [], } function RestoreNavigationState() { let base64Decoded = window.location.hash base64Decoded = base64Decoded.substring(1) let jsonDecoded try { jsonDecoded = Base64UrlDecodeString(base64Decoded) NavigationState = JSON.parse(jsonDecoded) } catch (error) { return } } function SaveNavigationState() { let jsonEncoded = JSON.stringify(NavigationState) let base64Encoded = Base64UrlEncodeString(jsonEncoded) window.history.pushState(null, "", "#" + base64Encoded) } function PushScreen(id, data) { NavigationState.ScreenStack.push({ Id: id, ...data }) SaveNavigationState() window.scrollTo({ top: 0, behavior: "instant" }) Redraw() } function PopScreen() { NavigationState.ScreenStack.pop() SaveNavigationState() window.scrollTo({ top: 0, behavior: "instant" }) Redraw() } function FirstScreen() { NavigationState.ScreenStack = [] PushScreen({ id: ScreenId.Main }) } function GetCurrentScreen() { let length = NavigationState.ScreenStack.length if (length > 0) { return NavigationState.ScreenStack[length - 1] } return {} } function IsSelected(categoryId) { if (categoryId % 2 == 0) { return StyleStoreCategory } else { return StyleStoreCategorySelected } } function C(tag, className) { return `${tag}.${className}` } function StoreCategory(categoryId, category) { return h( Div, { class: IsSelected(categoryId), onclick: function () { PushScreen(ScreenId.Category, { CategoryId: categoryId }) }, }, h( // Div, C(Div, StyleStoreItemPhoto), // { class: StyleStoreItemPhoto }, h(Img, { class: StyleStoreItemImage, src: StoreData.Categories[categoryId].FileUrl, }), ), h( Div, { class: StyleStoreItemLabel }, h(Span, { class: StyleStoreItemTitle }, category.Name), ), ) } function StoreItem() { return h( Div, { class: "cafe-item" }, h( StyleStoreItemCounter, { onupdate: function (_vnode) { if (!vnode.state.dirty) { return } vnode.state.dirty = false delta = vnode.state.count - vnode.state.oldCount var cur_anim_name = _vnode.dom.style["animation-name"] var anim_name = "" if (vnode.state.count > 0) { anim_name = "badge-show" if (delta > 0) { anim_name = "badge-incr" } else if (delta < 0) { anim_name = "badge-decr" } if ( (anim_name == "badge-incr" || anim_name == "badge-decr") && anim_name == cur_anim_name ) { anim_name += "2" } } else if (cur_anim_name != "") { anim_name = "badge-hide" } _vnode.dom.style["animation-name"] = anim_name }, }, vnode.state.count, ), h( ".cafe-item-photo", h( "picture.cafe-item-lottie", h(Img, { src: Data.general.items[vnode.state.id].file_url }), ), h( "span.cafe-item-new", { style: { "background-color": Data.general.items[vnode.state.id].badge_color, }, }, Data.general.items[vnode.state.id].badge_text, ), ), ) } function StoreItem(itemId, item) { return h( "div", { class: StyleStoreItem, onclick: function () { if (StoreData.Items[itemId].OptionsGroupIds) { PushScreen(ScreenId.Item, { ItemId: itemId }) } else { ShoppingCard.push(itemId) Redraw() } }, }, h( "div", { class: StyleStoreItemPhoto }, h("img", { class: StyleStoreItemImage, src: StoreData.Items[itemId].FileUrl, }), ), h( "div", { class: StyleStoreItemLabel }, h( "span", { class: "cafe-item-price" }, FormatPrice(StoreData.Items[itemId].Price), ), h( "span", { class: "cafe-item-title" }, StoreData.Items[itemId].Name, ), ), h( "div", { class: "cafe-item-buttons" }, h( "button", { class: "cafe-item-decr-button button-item", onclick: function () { ShoppingCard.pop() }, }, h("span", { class: "gg-math-minus" }), ), h( "button", { class: "cafe-item-incr-button button-item" }, h("span", { class: "button-item-icon gg-math-plus" }), h("span", { class: StyleButtonItemLabel }, "В корзину"), ), ), ) } let StyleBackButton = CreateStyle({ // "position": "absolute", // "left": "50%", // "top": "50%", // "transform": "translate(-50%, -50%)", "box-sizing": "border-box", "width": "95%", "background-color": "var(--button-color)", "border": "0", "outline": "border", // "margin": "1rem", "padding": "1rem", "font-size": "2rem", "font-family": "monospace", "box-shadow": "0px 5px 10px rgba(darken(dodgerblue, 40%))", "transition": "all .3s", "cursor": "pointer", "border-radius": "0px", "border-bottom": "4px solid lighten(gray, 70%)", "transform": "scale(0.95)", }) AddStyleTo(StyleBackButton, "hover", { "box-shadow": "0px 15px 25px -5px rgba(darken(dodgerblue, 40%))", "transform": "scale(1.0)", }) AddStyleTo(StyleBackButton, "active", { "box-shadow": "0px 4px 8px rgba(darken(dodgerblue, 30%))", "transform": "scale(0.9)", }) function Main() { if (NavigationState.ScreenStack.length > 0) { return h( "button", { class: StyleBackButton, onclick: function () { PopScreen() }, }, "Назад", ) } let currentScreen = GetCurrentScreen() switch (currentScreen.Id || ScreenId.Category) { case ScreenId.Unknown: break case ScreenId.Category: if (Object.keys(StoreData).length > 0) { let categories = [] let currentCategoryId = currentScreen.CategoryId for (let [_categoryId, category] of Object.entries( StoreData.Categories, )) { let categoryId = Number(_categoryId) if (category.ParentCategoryId != currentCategoryId) { continue } categories.push(StoreCategory(categoryId, category)) } let items = [] for (let [_itemId, item] of Object.entries(StoreData.Items)) { let itemId = Number(_itemId) if (item.CategoryId != currentCategoryId) { continue } items.push(StoreItem(itemId, item)) } return h( "div", { class: StyleStoreItems }, ...categories, ...items, ) } break } return h( "div", { class: StyleLoadingContainer }, h("div", { class: "loader" }), ) } function GetShoppingCardTotal() { let total = 0 // for (i in scores) { // } return total } function UpdateTelegramStuff() { Telegram.WebApp.isClosingConfirmationEnabled = !!ShoppingCard.length // if (NavigationState.ScreenStack.length > 0) { // Telegram.WebApp.BackButton.show() // } else { // Telegram.WebApp.BackButton.hide() // } if (ShoppingCard.length > 0) { if (false) { Telegram.WebApp.MainButton.setParams({ is_visible: true, has_shine_effect: true, }) } else { Telegram.WebApp.MainButton.setParams({ // is_visible: !!Data.CanPay, text: "Оплатить " + FormatPrice(GetShoppingCardTotal()), }).hideProgress() } } else { Telegram.WebApp.MainButton.setParams({ // is_visible: !!Data.CanPay, text: "Оформить заказ", }).hideProgress() } } let Page = { Store: 1, Chart: 2, } function Redraw() { let startTime = performance.now() UpdateTelegramStuff() if (!LoginData.Page) { LoginData.Page = Page.Store } switch (LoginData.Page) { case Page.Store: render(document.body, Main()) break case Page.Chart: render(document.body, ChartRender()) break } postRender() let endTime = performance.now() let t = Math.round((endTime - startTime) * 1000) console.log(`redraw took ${t} microseconds`) } function setThemeClass() { // document.documentElement.className = Telegram.WebApp.colorScheme; } function ChartRender() { return h( Div, {}, h("canvas", { id: "chart" }), h( "button", { onclick: function () { index = 0 mode = 1 UpdateChart() }, }, "Monthly", ), h( "button", { onclick: function () { index = 0 mode = 2 UpdateChart() }, }, "Weekly", ), h( "button", { onclick: function () { index = 0 mode = 3 UpdateChart() }, }, "Daily", ), h( "button", { onclick: function () { index += 1 let maxIndex = Math.floor( (getMaxIndex(mode) - 1) / MAX_PER_PAGE, ) console.log(maxIndex) if (index > maxIndex) { index = maxIndex } UpdateChart() }, }, "plus", ), h( "button", { onclick: function () { index -= 1 if (index < 0) { index = 0 } UpdateChart() }, }, "minus", ), ) } let index = Number.MAX_SAFE_INTEGER let mode = 1 function UpdateChart() { ChartObj.data = getData(mode, index) ChartObj.update() } let ChartData = {} var Utf8Encoder = new TextEncoder() var Utf8Decoder = new TextDecoder("utf-8") function Base64UrlEncodeString(s) { return Base64UrlEncodeArray(Utf8Encoder.encode(s)) } function Base64UrlDecodeString(s) { return Utf8Decoder.decode(Base64UrlDecodeArray(s)) } function Base64UrlEncodeArray(buffer) { return btoa( Array.from(new Uint8Array(buffer), (b) => String.fromCharCode(b)).join( "", ), ) .replace(/\+/g, "-") .replace(/\//g, "_") .replace(/=+$/, "") } function Base64UrlDecodeArray(value) { let m = value.length % 4 return Uint8Array.from( atob( value .replace(/-/g, "+") .replace(/_/g, "/") .padEnd(value.length + (m === 0 ? 0 : 4 - m), "="), ), (c) => c.charCodeAt(0), ).buffer } function LoadChartData() { fetch( "/api/chart?" + new URLSearchParams({ UserId: LoginData.UserId, Token: Base64UrlEncodeArray(LoginData.Token), StoreId: LoginData.StoreId, }), ) .then((response) => response.json()) .then((data) => { ChartData = data Redraw() }) .catch((error) => {}) } let ChartObj function postRender() { switch (LoginData.Page) { case Page.Store: break case Page.Chart: Chart.defaults.backgroundColor = Telegram.WebApp.themeParams.button_color Chart.defaults.borderColor = Telegram.WebApp.themeParams.hint_color Chart.defaults.color = Telegram.WebApp.themeParams.text_color let ctx = document.getElementById("chart") if (Object.keys(ChartData).length == 0) { return } ChartObj = new Chart(ctx, { type: "line", data: getData(mode, index), options: { plugins: { legend: { display: false, }, }, scales: { y: { suggestedMin: 0, }, }, }, }) break } } let MAX_PER_PAGE = 10 function getMaxIndex(mode) { if (mode == 1) { return Object.keys(ChartData.Monthly).length } if (mode == 2) { return Object.keys(ChartData.Weekly).length } if (mode == 3) { return Object.keys(ChartData.Daily).length } } function getData(mode, index) { let data if (mode == 1) { data = ChartData.Monthly } if (mode == 2) { data = ChartData.Weekly } if (mode == 3) { data = ChartData.Daily } let keys = Object.keys(data) let values = Object.values(data) let newKeys = keys.map((key) => { let date = new Date(Number(key) / 1_000_000) return date.toLocaleDateString("ru-RU") }) let newValues = values.map((value) => value / 100) if (index < 0) { index = 0 } let maxIndex = Math.floor((getMaxIndex(mode) - 1) / MAX_PER_PAGE) if (index > maxIndex) { index = maxIndex } let start = MAX_PER_PAGE * (index + 0) let end = MAX_PER_PAGE * (index + 1) start = Math.max(0, start) end = Math.max(0, end) start = Math.min(newKeys.length, start) end = Math.min(newKeys.length, end) newKeys = newKeys.slice(start, end) newValues = newValues.slice(start, end) return { labels: newKeys, datasets: [ { label: "Turkish lira", data: newValues, }, ], } } function Init() { // console.log(Data.userId); // console.log(Data.token); // if (!Data.token) { // Data.isClosed = true; // Data.error = "Заведение временно закрыто"; // // ShowStatus("Заведение временно закрыто"); // return; // } // $(".js-item").each(function (i) { // if (i == 0) { // return; // } // var itemEl = $(this); // itemEl.hide(); // }); // $('.js-order-edit').on('click', Store.EditClicked); // $(".js-status").on("click", Store.StatusClicked); // Telegram.WebApp.MainButton.setParams({ // // text_color: '#fff', // shine_effect: true, // }).onClick(Store.MainBtnClicked); Telegram.WebApp.ready() Telegram.WebApp.setHeaderColor("bg_color") Telegram.WebApp.expand() Telegram.WebApp.onEvent("themeChanged", setThemeClass) setThemeClass() // document.documentElement.style = document.documentElement.style + variables; // document.head.appendChild(bodyStyle); // Telegram.WebApp.BackButton.onClick(function () { // PopScreen() // }) RestoreNavigationState() LoadLoginData() LoadStoreData() LoadChartData() } // addEventListener("popstate", (event) => { // PopScreen() // }) Init() Redraw() function UpdateItem(itemEl, delta) { var price = +itemEl.data("item-price") var count = +itemEl.data("item-count") || 0 var counterEl = $(".js-item-counter", itemEl) counterEl.text(count ? count : 1) var isSelected = itemEl.hasClass("selected") var anim_name = isSelected ? delta > 0 ? "badge-incr" : count > 0 ? "badge-decr" : "badge-hide" : "badge-show" var cur_anim_name = counterEl.css("animation-name") if ( (anim_name == "badge-incr" || anim_name == "badge-decr") && anim_name == cur_anim_name ) { anim_name += "2" } counterEl.css("animation-name", anim_name) itemEl.toggleClass("selected", count > 0) var orderItemEl = Store.GetOrderItem(itemEl) var orderCounterEl = $(".js-order-item-counter", orderItemEl) orderCounterEl.text(count ? count : 1) orderItemEl.toggleClass("selected", count > 0) var orderPriceEl = $(".js-order-item-price", orderItemEl) var item_price = count * price orderPriceEl.text(Store.FormatPrice(item_price)) Store.UpdateTotalPrice() } function FormatPrice(price) { return Math.trunc(price / 100) + " " + StoreData.CurrencySign } function StoreItemLine(id) { return h( "div.cafe-order-item", h( "div.cafe-order-item-photo", h( "picture.cafe-item-lottie", h("img", { src: Data.general.items[id].file_url }), ), ), h( "div.cafe-order-item-label", h( "div", { class: StyleItemTitle }, Data.general.items[id].name, " ", h("span.cafe-order-item-counter", `${Data.ShoppingCard} шт`), ), h("div.cafe-order-item-description", "test"), ), h( "div.cafe-order-item-price", FormatPrice(Data.general.items[id].price), ), ) } function StoreTakeout() { return h( "div.cafe-order-overview", h( ".cafe-block", h( ".cafe-order-items", Object.entries(Data.general.items).map(function (d) { shopItemId = d[0] return h(StoreItemLine, { id: shopItemId }) }), ), ), h( ".cafe-switch-block", h(".cafe-switch-label", "Забрать на кассе"), h( ".cafe-switch", h( "label.switch", h("input", { type: "checkbox" }), h("span.slider"), ), ), ), h( ".cafe-switch-block", h(".cafe-switch-label", "Номер столика"), h("input", { class: StyleNumberInput }, { type: "text" }), ), h( ".cafe-text-field-wrap", h("textarea.cafe-text-field cafe-block", { rows: 1, placeholder: "Добавить комментарий…", style: "overflow: hidden visible; overflow-wrap: break-word;", oninput: function (_vnode) { autosize(this) }, }), ), ) } function StoreDelivery() { return h( "div.cafe-order-overview", h(".cafe-block"), h( ".cafe-switch-block", h(".cafe-switch-label", "Забрать на кассе"), h( ".cafe-switch", h( "label.switch", h("input", { type: "checkbox" }), h("span.slider"), ), ), ), h( ".cafe-switch-block", h(".cafe-switch-label", "Номер столика"), h("input", { class: StyleNumberInput }, { type: "text" }), ), h( ".cafe-text-field-wrap", h("textarea.cafe-text-field cafe-block", { rows: 1, placeholder: "Добавить комментарий…", style: "overflow: hidden visible; overflow-wrap: break-word;", oninput: function (_vnode) { autosize(this) }, }), ), ) } function StoreCashier() { return h( "div.cafe-order-overview", h(".cafe-block"), h( ".cafe-switch-block", h(".cafe-switch-label", "Наличные"), h( "label.checkcontainer", h("input", { type: "radio", name: "radio" }), h("span.radiobtn"), ), ), h( ".cafe-switch-block", h(".cafe-switch-label", "Безналичные"), h( "label.checkcontainer", h("input", { type: "radio", name: "radio" }), h("span.radiobtn"), ), ), h( ".cafe-switch-block", h(".cafe-switch-label", "Баланс"), h( "label.checkcontainer", h("input", { type: "radio", name: "radio" }), h("span.radiobtn"), ), ), h( ".cafe-switch-block", h(".cafe-switch-label", "Скидка"), h("input", { class: StyleNumberInput }, { type: "text" }), ), h( ".cafe-text-field-wrap", h("textarea.cafe-text-field cafe-block", { rows: 1, placeholder: "Добавить комментарий…", style: "overflow: hidden visible; overflow-wrap: break-word;", oninput: function (_vnode) { autosize(this) }, }), ), ) } function StoreOptions() { return h(".xxx") } function Main1() { categoryId = "" len = NavigationState.ScreenStateStack.length if (len > 0) { categoryId = NavigationState.ScreenStateStack[len - 1].CategoryId } // if (NavigationState.ScreenStateStack.length > 0) { // Telegram.WebApp.BackButton.show() // } else { // Telegram.WebApp.BackButton.hide() // } UpdateMainButton() if (Data.error) { return h( "div", { class: StyleStatusWrap }, m(".cafe-status .shown", Data.error), ) } else if (Data.general.categories) { // return m(StoreTakeout); return m( ".cafe-items start", Object.entries(Data.general.categories).map(function (d) { shopCategoryId = d[0] parent_category_id = Data.general.categories[shopCategoryId] .parent_category_id || "" if (parent_category_id != categoryId) { return } return h(StoreCategory, { id: shopCategoryId }) }), Object.entries(Data.general.items).map(function (d) { shopItemId = d[0] if (Data.general.items[shopItemId].category_id != categoryId) { return } return h(StoreItem, { id: shopItemId }) }), ) } else { return h("div", { class: StyleLoadingContainer }, m(".loader")) } }