diff --git a/mirzaev/arming_bot/system/controllers/cart.php b/mirzaev/arming_bot/system/controllers/cart.php index d955fd5..e91f0df 100755 --- a/mirzaev/arming_bot/system/controllers/cart.php +++ b/mirzaev/arming_bot/system/controllers/cart.php @@ -85,6 +85,31 @@ final class cart extends core 'products' => $this->cart?->products(language: $this->language, currency: $this->currency) ]; + if (!empty($this->view->cart['products'])) { + // Initialized products + + // Declaring buffer of formatted products + $formatted = []; + + foreach ($this->view->cart['products'] as $product) { + // Iterating over products + + // Formatting products + for ($i = 0; $i < $product['amount']; ++$i) { + $formatted[] = [ + 'weight' => $product['document']['weight'] ?? 0, + ...$product['document']['dimensions'] + ]; + } + } + + // Deinitializing unnecessary variables + unset($product); + + // Initializing formatted products + $this->view->formatted = $formatted; + } + // Initializing types of avaiabld deliveries $this->view->deliveries = [ 'cdek' => [ @@ -319,8 +344,33 @@ final class cart extends core if ($this->cart instanceof model) { // Initialized the cart - // Initializing summary data of the cart - $summary = $this->cart?->summary(currency: $this->currency, errors: $this->errors['cart']); + // Initializing products in the cart + $products = $this->cart->products(language: $this->language, currency: $this->currency); + + if (!empty($products)) { + // Initialized products + + // Initializing summary data of the cart + $summary = $this->cart?->summary(currency: $this->currency, errors: $this->errors['cart']); + + // Declaring buffer of formatted products + $formatted = []; + + foreach ($products as $product) { + // Iterating over products + + // Formatting products + for ($i = 0; $i < $product['amount']; ++$i) { + $formatted[] = [ + 'weight' => $product['document']['weight'] ?? 0, + ...$product['document']['dimensions'] + ]; + } + } + } + + // Deinitializing unnecessary variables + unset($product); // Sending response $this->response @@ -330,6 +380,7 @@ final class cart extends core ->json([ 'cost' => $summary['cost'] ?? 0, 'amount' => $summary['amount'] ?? 0, + 'products' => $formatted ?? [], 'errors' => $this->errors ]) ->validate($this->request) diff --git a/mirzaev/arming_bot/system/controllers/catalog.php b/mirzaev/arming_bot/system/controllers/catalog.php index f700fed..3861e05 100755 --- a/mirzaev/arming_bot/system/controllers/catalog.php +++ b/mirzaev/arming_bot/system/controllers/catalog.php @@ -148,7 +148,7 @@ final class catalog extends core $this->core->request(new request('PATCH', '/account/write', protocol::http_3, parameters: ['catalog_filters_brand' => $brand ?? null])); // Writing to the current implementator of the buffer - $this->session->buffer = ['catalog' => ['filters' => ['brand' => $brand ?? null]]] + $this->session->buffer ?? []; + $this->session->buffer = ['catalog' => ['filters' => ['brand' => $brand ?? null]]] + ($this->session->buffer ?? []); // Initialize buffer of filters query (AQL) $_sort = 'd.position ASC, d.name ASC, d.created DESC'; diff --git a/mirzaev/arming_bot/system/controllers/delivery.php b/mirzaev/arming_bot/system/controllers/delivery.php index 825c198..5377d4a 100755 --- a/mirzaev/arming_bot/system/controllers/delivery.php +++ b/mirzaev/arming_bot/system/controllers/delivery.php @@ -58,8 +58,9 @@ final class delivery extends core * Validate and write delivery data to account and session buffers * * @param string|null $company Name of delivery company - * @param ?string $location location - * @param ?string $street Address with street and house + * @param string|null $location Location (city) + * @param string|null $street Address (street with house) + * @param string|int|null $type Type or taruff * * @return null */ @@ -68,7 +69,8 @@ final class delivery extends core string|null $company = null, /* string|location|null $location = null, */ ?string $location = null, - ?string $street = null + ?string $street = null, + string|int|null $type = null ): null { if (str_contains($this->request->headers['accept'], content::json->value)) { // Request for JSON response @@ -102,6 +104,53 @@ final class delivery extends core // Writing to the buffer of the response /* $response['company'] = $normalized; */ + // Initializing the cart + $this->cart ??= $this->account?->cart() ?? $this->session?->cart(); + + if ($this->cart instanceof cart) { + // Initialized the cart + + // Initializing products in the cart + $products = $this->cart->products(language: $this->language, currency: $this->currency); + + // Declaring buffer of formatted products + $formatted = []; + + if (!empty($products)) { + // Initialized products + + foreach ($products as $product) { + // Iterating over products + + // Formatting products + for ($i = 0; $i < $product['amount']; ++$i) { + $formatted[] = [ + 'weight' => $product['document']['weight'] ?? 0, + ...$product['document']['dimensions'] + ]; + } + } + } + + // Deinitializing unnecessary variables + unset($product); + + // Writing delivery section to the buffer of the response (@todo add check for exists) + $response['delivery'] = [ + 'html' => $this->view->render('cart/elements/deliveries/' . $normalized . '/section.html'), + 'javascript' => match ($normalized) { + 'cdek' => [ + [ + 'code' => $this->view->render('cart/elements/deliveries/' . $normalized . '/javascript.html', [ + 'formatted' => $formatted + ]) + ] + ], + default => null + } + ]; + } + // Initialization buffer of delivery parameters $delivery = $this->account?->buffer['delivery'] ?? $this->session?->buffer['delivery'] ?? []; @@ -174,7 +223,6 @@ final class delivery extends core $locations = null; if ($delivery['company'] === 'cdek') { - // Delivery by CDEK // Searching for locations by name (first part with spaces before first comma or any non word symbol) $cdek = cdek::location($normalized[0], $this->errors['delivery'])?->items; @@ -250,42 +298,45 @@ final class delivery extends core // Reinitializating locations from buffer of validated locations by input values $locations = $buffer; - if (count($locations) === 1) { - // Identificated location + /* if (count($locations) === 1) { */ + // Identificated location - // Writing to the session buffer - $this->core->request(new request('PATCH', '/session/write', protocol::http_3, parameters: [$name = 'delivery_' . $delivery['company'] . '_location' => $locations[0]])); + // Writing to the session buffer + $this->core->request(new request('PATCH', '/session/write', protocol::http_3, parameters: [$name = 'delivery_' . $delivery['company'] . '_location' => $locations[0]])); - // Writing to the account buffer - $this->core->request(new request('PATCH', '/account/write', protocol::http_3, parameters: [$name => $locations[0]])); + // Writing to the account buffer + $this->core->request(new request('PATCH', '/account/write', protocol::http_3, parameters: [$name => $locations[0]])); - // Deinitializing unnecessary variables - unset($name); + // Deinitializing unnecessary variables + unset($name); - // Writing result value of location name - $result = $locations[0]['name'] . ', ' . implode(', ', array_reverse($locations[0]['structure'])); + // Writing result value of location name + $result = $locations[0]['name'] . ', ' . implode(', ', array_reverse($locations[0]['structure'])); - // Writing location data to the buffer of the response - /* $response['location'] = [ + // Writing location data to the buffer of the response + /* $response['location'] = [ 'identifier' => $locations[0]['identifier'], 'input' => $result ]; */ - if (!empty($delivery[$delivery['company']]['street'])) { - // Required parameters initialized: company, location, street + // Writing status of execution to the buffer of the response + $response['status'] = 'success'; - // Writing readiness status to the buffer of the response - $response['ready'] = true; + if (!empty($delivery[$delivery['company']]['street'])) { + // Required parameters initialized: company, location, street - // Writing to the session buffer - $this->core->request(new request('PATCH', '/session/write', protocol::http_3, parameters: [$name = 'delivery_' . $delivery['company'] . '_ready' => true])); + // Writing readiness status to the buffer of the response + $response['ready'] = true; - // Writing to the account buffer - $this->core->request(new request('PATCH', '/account/write', protocol::http_3, parameters: [$name => true])); + // Writing to the session buffer + $this->core->request(new request('PATCH', '/session/write', protocol::http_3, parameters: [$name = 'delivery_' . $delivery['company'] . '_ready' => true])); - // Deinitializing unnecessary variables - unset($name); - } else { + // Writing to the account buffer + $this->core->request(new request('PATCH', '/account/write', protocol::http_3, parameters: [$name => true])); + + // Deinitializing unnecessary variables + unset($name); + /* } else { // Not initialized required parameters // Writing to the session buffer @@ -304,10 +355,7 @@ final class delivery extends core // Deinitializing unnecessary variables unset($name_ready, $name_cost, $name_days); - } - - // Writing status of execution to the buffer of the response - $response['status'] = 'success'; + } */ // Writing locations into response buffer $response['locations'] = []; @@ -428,7 +476,7 @@ final class delivery extends core $normalized = ''; // Normalizing street - if (preg_match('/[\w\d\s]+/u', urldecode($street), $matches)) $normalized = mb_ucfirst($matches[0] ?? ''); + if (preg_match('/[\w\d\s\.\,]+/u', urldecode($street), $matches)) $normalized = mb_ucfirst($matches[0] ?? ''); // Deinitializing unnecessary variables unset($matches); @@ -502,6 +550,79 @@ final class delivery extends core // Deinitializing unnecessary variables unset($normalized); } + } else if (isset($type)) { + // Received delivery type + + if ((is_string($type) && mb_strlen($type) < 30) || (is_int($type && $type < 10000))) { + // Validated delivery type + + // Declating variable for result value of delivery type + $result = ''; + + // Declating variable for normalized value of delivery type + $normalized = ''; + + // Normalizing location name + if (preg_match('/[\w\d]+/', trim(urldecode($type)), $matches)) $normalized = $matches[0]; + + // Deinitializing unnecessary variables + unset($matches); + + // Initialization buffer of delivery parameters + $delivery = $this->account?->buffer['delivery'] ?? $this->session?->buffer['delivery'] ?? []; + + if (isset($delivery['company'])) { + // Initialized delivery company + + if (!empty($normalized)) { + // Normalized delivery type + + // Writing to the session buffer + $this->core->request(new request('PATCH', '/session/write', protocol::http_3, parameters: [$name = 'delivery_' . $delivery['company'] . '_type' => $normalized])); + + // Writing to the account buffer + $this->core->request(new request('PATCH', '/account/write', protocol::http_3, parameters: [$name => $normalized])); + + // Deinitializing unnecessary variables + unset($name); + + // Writing result value of delivery type + $result = $normalized; + + // Writing status of execution to the buffer of the response + $response['status'] = 'success'; + + // Deinitializing unnecessary variables + unset($normalized); + } else { + // Value is empty after separating + + // Not initialized required parameters + + // Writing to the session buffer + $this->core->request(new request('PATCH', '/session/write', protocol::http_3, parameters: [ + $name_type = 'delivery_' . $delivery['company'] . '_type' => null, + $name_ready = 'delivery_' . $delivery['company'] . '_ready' => false, + $name_cost = 'delivery_' . $delivery['company'] . '_cost' => null, + $name_days = 'delivery_' . $delivery['company'] . '_days' => null + ])); + + // Writing to the account buffer + $this->core->request(new request('PATCH', '/account/write', protocol::http_3, parameters: [ + $name_type => null, + $name_ready => false, + $name_cost => null, + $name_days => null + ])); + + // Deinitializing unnecessary variables + unset($name_type, $name_ready, $name_cost, $name_days); + } + } + + // Deinitializing unnecessary variables + unset($delivery, $location, $result, $normalized); + } } // Sending response @@ -588,8 +709,7 @@ final class delivery extends core from_street: 'Екатерининская 116', // @todo issues #13 to_location: $delivery[$delivery['company']]['location']['identifier'], to_street: $delivery[$delivery['company']]['street'], - tariff: 368, // ИМ : warehouse-terminal (склад-постамат) - // tariff: 486, // Обычная доставка : warehouse-terminal (склад-постамат) + tariff: $delivery[$delivery['company']]['type'] ?? 368, products: $formatted, date: new datetime(), // @todo weekdays only? + timezones errors: $this->errors['delivery'] @@ -636,12 +756,15 @@ final class delivery extends core ], 'street' => $delivery[$delivery['company']]['street'], 'cost' => $cdek->total_sum, - 'days' => $cdek->calendar_max + 'days' => $cdek->calendar_max, + 'type' => $delivery[$delivery['company']]['type'] ?? 368, ]], $this->errors['buffer']); // Writing to response buffer $response['cost'] = $cdek->total_sum; $response['days'] = $cdek->calendar_max; + $response['longitude'] = $delivery[$delivery['company']]['location']['data']['longitude']; + $response['latitude'] = $delivery[$delivery['company']]['location']['data']['latitude']; } } diff --git a/mirzaev/arming_bot/system/models/session.php b/mirzaev/arming_bot/system/models/session.php index 0564ef8..bc0ad33 100755 --- a/mirzaev/arming_bot/system/models/session.php +++ b/mirzaev/arming_bot/system/models/session.php @@ -268,10 +268,12 @@ final class session extends core implements document_interface, collection_inter <<<'AQL' FOR d IN @@collection FILTER d.address == @address && d.expires > @time && d.active == true + SORT d.updated DESC + LIMIT 1 RETURN d AQL, [ - '@collection' => static::COLLECTION, + '@collection' => static::COLLECTION, 'address' => $address, 'time' => time() ], diff --git a/mirzaev/arming_bot/system/public/cdek.php b/mirzaev/arming_bot/system/public/cdek.php new file mode 100755 index 0000000..e1f64ad --- /dev/null +++ b/mirzaev/arming_bot/system/public/cdek.php @@ -0,0 +1,348 @@ +process($_GET, file_get_contents('php://input')); + +class service +{ + /** + * @var string Auth login + */ + private $login; + /** + * @var string Auth pwd + */ + private $secret; + /** + * @var string Base Url for API 2.0 Production + */ + private $baseUrl; + /** + * @var string Auth Token + */ + private $authToken; + /** + * @var array Data From Request + */ + private $requestData; + /** @var array Request metrics */ + private $metrics; + + public function __construct($login, $secret, $baseUrl = 'https://api.cdek.ru/v2') + { + $this->login = $login; + $this->secret = $secret; + $this->baseUrl = $baseUrl; + $this->metrics = array(); + } + + public function process($requestData, $body) + { + $time = $this->startMetrics(); + + $this->requestData = array_merge($requestData, json_decode($body, true) ?: array()); + + if (!isset($this->requestData['action'])) { + $this->sendValidationError('Action is required'); + } + + $this->getAuthToken(); + + switch ($this->requestData['action']) { + case 'offices': + $this->sendResponse($this->getOffices(), $time); + break; + case 'calculate': + $this->sendResponse($this->calculate(), $time); + break; + default: + $this->sendValidationError('Unknown action'); + } + } + + private function sendValidationError($message) + { + $this->http_response_code(400); + header('Content-Type: application/json'); + header('X-Service-Version: 3.11.1'); + echo json_encode(array('message' => $message)); + exit(); + } + + private function http_response_code($code) + { + switch ($code) { + case 100: + $text = 'Continue'; + break; + case 101: + $text = 'Switching Protocols'; + break; + case 200: + $text = 'OK'; + break; + case 201: + $text = 'Created'; + break; + case 202: + $text = 'Accepted'; + break; + case 203: + $text = 'Non-Authoritative Information'; + break; + case 204: + $text = 'No Content'; + break; + case 205: + $text = 'Reset Content'; + break; + case 206: + $text = 'Partial Content'; + break; + case 300: + $text = 'Multiple Choices'; + break; + case 301: + $text = 'Moved Permanently'; + break; + case 302: + $text = 'Moved Temporarily'; + break; + case 303: + $text = 'See Other'; + break; + case 304: + $text = 'Not Modified'; + break; + case 305: + $text = 'Use Proxy'; + break; + case 400: + $text = 'Bad Request'; + break; + case 401: + $text = 'Unauthorized'; + break; + case 402: + $text = 'Payment Required'; + break; + case 403: + $text = 'Forbidden'; + break; + case 404: + $text = 'Not Found'; + break; + case 405: + $text = 'Method Not Allowed'; + break; + case 406: + $text = 'Not Acceptable'; + break; + case 407: + $text = 'Proxy Authentication Required'; + break; + case 408: + $text = 'Request Time-out'; + break; + case 409: + $text = 'Conflict'; + break; + case 410: + $text = 'Gone'; + break; + case 411: + $text = 'Length Required'; + break; + case 412: + $text = 'Precondition Failed'; + break; + case 413: + $text = 'Request Entity Too Large'; + break; + case 414: + $text = 'Request-URI Too Large'; + break; + case 415: + $text = 'Unsupported Media Type'; + break; + case 500: + $text = 'Internal Server Error'; + break; + case 501: + $text = 'Not Implemented'; + break; + case 502: + $text = 'Bad Gateway'; + break; + case 503: + $text = 'Service Unavailable'; + break; + case 504: + $text = 'Gateway Time-out'; + break; + case 505: + $text = 'HTTP Version not supported'; + break; + default: + exit('Unknown http status code "' . htmlentities($code) . '"'); + } + + $protocol = (isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0'); + header($protocol . ' ' . $code . ' ' . $text); + $GLOBALS['http_response_code'] = $code; + } + + private function getAuthToken() + { + $time = $this->startMetrics(); + + $token = $this->httpRequest('oauth/token', array( + 'grant_type' => 'client_credentials', + 'client_id' => $this->login, + 'client_secret' => $this->secret, + ), true); + + $this->endMetrics('auth', 'Server Auth Time', $time); + + $result = json_decode($token['result'], true); + + if (!isset($result['access_token'])) { + throw new RuntimeException('Server not authorized to CDEK API'); + } + + $this->authToken = $result['access_token']; + } + + private function startMetrics() + { + return function_exists('hrtime') ? hrtime(true) : microtime(true); + } + + private function httpRequest($method, $data, $useFormData = false, $useJson = false) + { + $ch = curl_init("$this->baseUrl/$method"); + + $headers = array( + 'Accept: application/json', + 'X-App-Name: widget_pvz', + 'X-App-Version: 3.11.1' + ); + + if ($this->authToken) { + $headers[] = "Authorization: Bearer $this->authToken"; + } + + if ($useFormData) { + curl_setopt_array($ch, array( + CURLOPT_POST => true, + CURLOPT_POSTFIELDS => $data, + )); + } elseif ($useJson) { + $headers[] = 'Content-Type: application/json'; + curl_setopt_array($ch, array( + CURLOPT_POST => true, + CURLOPT_POSTFIELDS => json_encode($data), + )); + } else { + curl_setopt($ch, CURLOPT_URL, "$this->baseUrl/$method?" . http_build_query($data)); + } + + curl_setopt_array($ch, array( + CURLOPT_USERAGENT => 'widget/3.11.1', + CURLOPT_HTTPHEADER => $headers, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_HEADER => true, + )); + + $response = curl_exec($ch); + $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE); + $headers = substr($response, 0, $headerSize); + $result = substr($response, $headerSize); + + $addedHeaders = $this->getHeaderValue($headers); + + if ($result === false) { + throw new RuntimeException(curl_error($ch), curl_errno($ch)); + } + + return array('result' => $result, 'addedHeaders' => $addedHeaders); + } + + private function getHeaderValue($headers) + { + $headerLines = explode("\r\n", $headers); + return array_filter($headerLines, static function ($line) { + return !empty($line) && stripos($line, 'X-') !== false; + }); + } + + private function endMetrics($metricName, $metricDescription, $start) + { + $this->metrics[] = array( + 'name' => $metricName, + 'description' => $metricDescription, + 'time' => round( + function_exists('hrtime') ? (hrtime(true) - $start) / 1e+6 : (microtime(true) - $start) * 1000, + 2 + ), + ); + } + + private function sendResponse($data, $start) + { + $this->http_response_code(200); + header('Content-Type: application/json'); + header('X-Service-Version: 3.11.1'); + if (!empty($data['addedHeaders'])) { + foreach ($data['addedHeaders'] as $header) { + header($header); + } + } + + $this->endMetrics('total', 'Total Time', $start); + + if (!empty($this->metrics)) { + header('Server-Timing: ' . array_reduce($this->metrics, function ($c, $i) { + return $c . $i['name'] . ';desc="' . $i['description'] . '";dur=' . $i['time'] . ','; + }, '')); + } + + echo $data['result']; + + exit(); + } + + protected function getOffices() + { + $time = $this->startMetrics(); + $result = $this->httpRequest('deliverypoints', $this->requestData); + + $this->endMetrics('office', 'Offices Request', $time); + return $result; + } + + protected function calculate() + { + $time = $this->startMetrics(); + $result = $this->httpRequest('calculator/tarifflist', $this->requestData, false, true); + + $this->endMetrics('calc', 'Calculate Request', $time); + return $result; + } +} diff --git a/mirzaev/arming_bot/system/public/js/modules/cart.mjs b/mirzaev/arming_bot/system/public/js/modules/cart.mjs index 41940d0..c690cfb 100755 --- a/mirzaev/arming_bot/system/public/js/modules/cart.mjs +++ b/mirzaev/arming_bot/system/public/js/modules/cart.mjs @@ -799,6 +799,15 @@ Object.assign( cost.innerText = json.cost; } + // Dispatching event + document.dispatchEvent( + new CustomEvent("core.cart.summary.received", { + detail: { + json, + }, + }), + ); + // Exit (success) resolve(json); } diff --git a/mirzaev/arming_bot/system/public/js/modules/catalog.mjs b/mirzaev/arming_bot/system/public/js/modules/catalog.mjs index 01862b7..d18617c 100755 --- a/mirzaev/arming_bot/system/public/js/modules/catalog.mjs +++ b/mirzaev/arming_bot/system/public/js/modules/catalog.mjs @@ -329,6 +329,7 @@ Object.assign( exit_icon.classList.add("icon", "close"); const images = document.createElement("div"); + images.setAttribute("id", "images"); images.classList.add("images", "unselectable"); for ( @@ -350,7 +351,8 @@ Object.assign( let width = 0; let buffer; [...images.children].forEach( - (child) => (width += child.offsetWidth + + // 150px instead of child.offsetWidth by min-width in window.css + (child) => (width += 150 + (isNaN( buffer = parseFloat( getComputedStyle(child).marginRight, @@ -368,66 +370,84 @@ Object.assign( images.addEventListener("mousedown", _images_from); images.addEventListener("touchstart", _images_from); + let touches; + images.addEventListener('touchmove', (move) => { + touches = move.touches; + }); + const _open = (event) => { if ( event.type === "touchstart" || event.button === 0 ) { - { - const x = event.pageX || event.touches[0].pageX; - const y = event.pageY || event.touches[0].pageY; - const _x = images_from.pageX || - images_from.touches[0].pageX; - const _y = images_from.pageY || - images_from.touches[0].pageY; + const x = event.pageX || + (event.touches && event.touches[0]?.pageX) || 0; + const y = event.pageY || + (event.touches && event.touches[0]?.pageY) || 0; + const _x = images_from.pageX || + (images_from.touches && + images_from.touches[0]?.pageX) || + 0; + const _y = images_from.pageY || + (images_from.touches && + images_from.touches[0]?.pageY) || + 0; - if ( - _x - x < 10 && - _x - x > -10 && - _y - y < 10 && - _y - y > -10 - ) { - // Replacing small images with big images - Array.from(images.children).forEach((image) => - image.setAttribute( - "src", - image.getAttribute("data-image-big"), - ) - ); + if ( + _x - x < 10 && + _x - x > -10 && + _y - y < 10 && + _y - y > -10 + ) { + // Replacing small images with big images + Array.from(images.children).forEach((image) => + image.setAttribute( + "src", + image.getAttribute("data-image-big"), + ) + ); - // Expanding the "Web App" window - core.telegram.api.expand(); + // Expanding the "Web App" window + core.telegram.api.expand(); + core.telegram.api.disableVerticalSwipes(); - images.classList.add("extend"); + images.classList.add("extend"); - if (button) { - core.telegram.api.MainButton.hide(); - } - - setTimeout(() => { - images.hotline.step = 0; - images.hotline.wheel = false; - images.hotline.start(); - images.addEventListener("mouseup", _close); - images.addEventListener("touchend", _close); - }, 300); - images.removeEventListener("mouseup", _open); - images.removeEventListener("touchend", _open); + if (button) { + core.telegram.api.MainButton.hide(); } + + setTimeout(() => { + images.hotline.alive = false; + images.hotline.movable = false; + images.hotline.restart(); + + images.addEventListener("mouseup", _close); + images.addEventListener("touchend", _close); + }, 300); + images.removeEventListener("mouseup", _open); + images.removeEventListener("touchend", _open); } } }; const _close = (event) => { - const x = event.pageX || event.touches[0].pageX; - const y = event.pageY || event.touches[0].pageY; + console.log(event) + const x = event.pageX || + (touches && touches[0]?.pageX) || 0; + const y = event.pageY || + (touches && touches[0]?.pageY) || 0; const _x = images_from.pageX || - images_from.touches[0].pageX; + (images_from.touches && + images_from.touches[0]?.pageX) || + 0; const _y = images_from.pageY || - images_from.touches[0].pageY; + (images_from.touches && + images_from.touches[0]?.pageY) || + 0; if ( - event.type === "touchstart" || + event.type === "touchend" || event.button === 0 ) { if ( @@ -440,8 +460,11 @@ Object.assign( // (в идеале надо переделать на таймер 2 секунды есди зажата кнопка то ничего не делать а просто двигать) // пох абсолютно сейчас заказчик слишком охуевший для этого - images.hotline.step = -0.3; + images.hotline.movable = true; + images.hotline.alive = true; + images.hotline.step = -1; images.hotline.wheel = true; + images.hotline.restart(); if (width < card.offsetWidth) { images.hotline.stop(); @@ -457,6 +480,9 @@ Object.assign( images.classList.remove("extend"); + + core.telegram.api.enableVerticalSwipes(); + if (button) { core.telegram.api.MainButton.show(); } @@ -465,10 +491,30 @@ Object.assign( images.removeEventListener("touchend", _close); images.addEventListener("mousedown", _start); images.addEventListener("touchstart", _start); + } else { + // Курсор был сдвинут более чем на 10 пикселей + + if (x > _x) images.hotline.forward(); + else images.hotline.backward(); } } }; + const _start = (event) => { + if ( + event.type === "touchstart" || + event.button === 0 + ) { + images.removeEventListener("mousedown", _start); + images.removeEventListener("touchstart", _start); + images.addEventListener("mouseup", _open); + images.addEventListener("touchend", _open); + } + }; + + images.addEventListener("mousedown", _start); + images.addEventListener("touchstart", _start); + const header = document.createElement("p"); header.classList.add("header"); @@ -610,7 +656,6 @@ Object.assign( wrap.addEventListener("touchstart", _from); const remove = (event) => { - console.log("BABLO: " + typeof event); if ( typeof event === "undefined" || event.type !== "popstate" @@ -625,8 +670,6 @@ Object.assign( if (parameters.get("product") === identifier) { // The previous window with the product card was exactly the same - console.log("aboba"); - // Deleting product card parameters.delete("product"); @@ -698,38 +741,26 @@ Object.assign( core.telegram.api.BackButton.show(); core.telegram.api.BackButton.onClick(remove); - setTimeout(() => { - import("./hotline.js").then((hotline) => { - // Imported the hotline module + // setTimeout(() => { + import("./hotline.mjs").then((hotline) => { + // Imported the hotline module + images.hotline = new hotline.default( + images, + ); + images.hotline.step = -1; + images.hotline.interval = 20; + images.hotline.wheel = true; + images.hotline.touch = true; + images.hotline.events.set("transfer.beginning", true); + images.hotline.events.set("transfer.end", true); + images.hotline.events.set("moved.forward", true); + images.hotline.events.set("moved.backward", true); - const _start = (event) => { - if ( - event.type === "touchstart" || - event.button === 0 - ) { - images.removeEventListener("mousedown", _start); - images.removeEventListener("touchstart", _start); - images.addEventListener("mouseup", _open); - images.addEventListener("touchend", _open); - } - }; - - images.addEventListener("mousedown", _start); - images.addEventListener("touchstart", _start); - - images.hotline = new hotline.default( - json.product.identfier, - images, - ); - images.hotline.step = -0.3; - images.hotline.wheel = true; - images.hotline.touch = true; - - if (width > card.offsetWidth) { - images.hotline.start(); - } - }); - }, 300); + if (width > card.offsetWidth) { + images.hotline.start(); + } + }); + // }, 300); } }); diff --git a/mirzaev/arming_bot/system/public/js/modules/damper.mjs b/mirzaev/arming_bot/system/public/js/modules/damper.mjs index d148cac..d0b0afc 100755 --- a/mirzaev/arming_bot/system/public/js/modules/damper.mjs +++ b/mirzaev/arming_bot/system/public/js/modules/damper.mjs @@ -49,7 +49,7 @@ export default function damper(func, timeout = 300, force) { // Requested execution with ignoring the timer // Deleting the force argument - if (typeof force === "number") delete args[force - 1]; + if (typeof force === "number") args.splice(force - 1, force); // Writing promise handlers into the arguments variable args.push(resolve, reject); diff --git a/mirzaev/arming_bot/system/public/js/modules/delivery.mjs b/mirzaev/arming_bot/system/public/js/modules/delivery.mjs index 5d29a3e..b1faf72 100755 --- a/mirzaev/arming_bot/system/public/js/modules/delivery.mjs +++ b/mirzaev/arming_bot/system/public/js/modules/delivery.mjs @@ -93,7 +93,7 @@ export default class delivery { // Initializeg the delivery data request
element // Hiding the delivery data request
element - request.classList.add("deleted"); + request.classList.add("hidden"); } } else { // Not received readiness status or readiness status is false @@ -102,7 +102,7 @@ export default class delivery { // Initializeg the delivery data request
element // Hiding the delivery data request
element - request.classList.remove("deleted"); + request.classList.remove("hidden"); } } @@ -122,6 +122,100 @@ export default class delivery { button.checked = true; } } + + if (json.delivery) { + // Received delivery HTML-code + + core.modules.connect(["telegram"]) + .then(() => { + // + + core.telegram.api.LocationManager.init(() => { + //if (core.telegram.api.LocationManager.isAccessRequested && !core.telegram.api.LocationManager.isAccessGranted) { + // alert('Предоставьте разрешение на доступ к геопозиции'); + // core.telegram.api.LocationManager.openSettings(); + //} + + if (!core.telegram.api.LocationManager.isLocationAvailable) { + // Dispatching event + document.dispatchEvent( + new CustomEvent("core.telegram.api.location.rejected"), + ); + } else { + core.telegram.api.LocationManager.getLocation( + (location) => { + // Dispatching event + document.dispatchEvent( + new CustomEvent( + "core.telegram.api.location.received", + { + detail: { + location, + }, + }, + ), + ); + }, + ); + } + }); + }); + + // Initializing the deliveries
element + const deliveries = document.getElementById("deliveries"); + + if (deliveries instanceof HTMLElement) { + // Initialized the deliveries
element + + // Initializing the deliveries
element + let section = deliveries.nextElementSibling; + + if (section instanceof HTMLElement) { + // Initialized the deliveries
element + + // Deinitializing the delivery
element + section.remove(); + } + + // Creating the delivery
element + section = document.createElement("section"); + + // Writing the delivery
element after the delivery
element + deliveries.parentElement.insertBefore( + section, + deliveries.nextElementSibling, + ); + + // Reinitializing the delivery
element + section.outerHTML = json.delivery.html; + + // Reinitializing the deliveries
element + section = deliveries.nextElementSibling; + + for (const javascript of json.delivery.javascript) { + // Received delivery JavaScript-code and delivery JavaScript-links + + // Initializing the delivery JavaScript-code
-
+

{{ language.name == 'ru' ? 'Укажите данные для доставки' : 'Enter delivery information' }} diff --git a/mirzaev/arming_bot/system/views/themes/default/cart/elements/order.html b/mirzaev/arming_bot/system/views/themes/default/cart/elements/order.html new file mode 100755 index 0000000..9ae322b --- /dev/null +++ b/mirzaev/arming_bot/system/views/themes/default/cart/elements/order.html @@ -0,0 +1,5 @@ +{% if cart.products is not empty %} + +{% endif %} diff --git a/mirzaev/arming_bot/system/views/themes/default/cart/elements/summary.html b/mirzaev/arming_bot/system/views/themes/default/cart/elements/summary.html index 10bacdc..bcf77e0 100755 --- a/mirzaev/arming_bot/system/views/themes/default/cart/elements/summary.html +++ b/mirzaev/arming_bot/system/views/themes/default/cart/elements/summary.html @@ -3,7 +3,7 @@ class="rounded column unselectable">

{{ cart.summary.amount ?? 0 }} - {{ language.name == "ru" ? "товаров на сумму" : "products worth" }} + {{ language.name == "ru" ? "товаров за " : "products worth" }} {{ cart.summary.cost ?? 0 }} {% if session.buffer.delivery[account.buffer.delivery.company ?? session.buffer.delivery.company].cost %} {{ session.buffer.delivery[account.buffer.delivery.company ?? session.buffer.delivery.company].cost }} @@ -11,9 +11,6 @@ {% if session.buffer.delivery[account.buffer.delivery.company ?? session.buffer.delivery.company].days %} {{ session.buffer.delivery[account.buffer.delivery.company ?? session.buffer.delivery.company].days }} {% endif %} -
{% endif %} diff --git a/mirzaev/arming_bot/system/views/themes/default/cart/page.html b/mirzaev/arming_bot/system/views/themes/default/cart/page.html index 0b496a0..f550188 100755 --- a/mirzaev/arming_bot/system/views/themes/default/cart/page.html +++ b/mirzaev/arming_bot/system/views/themes/default/cart/page.html @@ -16,6 +16,7 @@

{{ h2 }}

{% include "/themes/default/cart/elements/delivery.html" %} {% include "/themes/default/cart/elements/summary.html" %} +{% include "/themes/default/cart/elements/order.html" %} {% include "/themes/default/cart/elements/products.html" %} {% endblock %} diff --git a/mirzaev/arming_bot/system/views/themes/default/catalog/page.html b/mirzaev/arming_bot/system/views/themes/default/catalog/page.html index 1921a4c..ddf9890 100755 --- a/mirzaev/arming_bot/system/views/themes/default/catalog/page.html +++ b/mirzaev/arming_bot/system/views/themes/default/catalog/page.html @@ -23,5 +23,5 @@ {{ parent() }} - + {% endblock %}