\\r\\n \\r\\n \\r\\n \\r\\n \\r\\n \\r\\n \\r\\n {{ prod.valorPromocao || prod.valorVenda || prod.valorRegular ? 'R$' + utils.convert((prod.valorPromocao || prod.valorVenda || prod.valorRegular) || 0, 'numberToPriceBr') : '' }}\\r\\n \\r\\n \\r\\n {{ ' R$ ' + utils.convert((prod.valorVenda || prod.valorRegular), 'numberToPriceBr') }}\\r\\n \\r\\n \\r\\n \\r\\n \\r\\n \\r\\n \\r\\n \\r\\n \\r\\n \\r\\n \\r\\n\\r\\n \\r\\n \\r\\n \\r\\n \\r\\n \\r\\n {{ categoryLengths[prod.categoriaId].descricao }}\\r\\n \\r\\n \\r\\n \\r\\n \\r\\n \\r\\n \\r\\n\\r\\n\\r\\n\\r\\n \\r\\n \\r\\n \\r\\n \\r\\n \\r\\n 0\\\"\\r\\n style=\\\"font-size: 12px; background-color: yellow; color: black; vertical-align: middle; position: relative; margin-left: 30px; margin-bottom: 10px;\\\"\\r\\n >{{ cart.getTotalItems() }}\\r\\n \\r\\n \\r\\n \\r\\n \\r\\n \\r\\n \\r\\n \\r\\n \\r\\n {{ auth.getTable() }}\\r\\n \\r\\n \\r\\n \\r\\n \\r\\n \\r\\n \\r\\n \\r\\n \\r\\n \\r\\n SENHA\\r\\n \\r\\n \\r\\n {{ getPedidoId() }}\\r\\n \\r\\n \\r\\n \\r\\n \\r\\n \\r\\n \\r\\n \\r\\n R$\\r\\n \\r\\n \\r\\n \\r\\n \\r\\n {{ utils.convert(cart.getTotalValue(), 'numberToPriceBr') }}\\r\\n \\r\\n \\r\\n \\r\\n \\r\\n \\r\\n \\r\\n \\r\\n\";","import { NgModule } from '@angular/core';\r\nimport { Routes, RouterModule } from '@angular/router';\r\n\r\nimport { CategoryNewPage } from './category-new.page';\r\n\r\nconst routes: Routes = [\r\n {\r\n path: '',\r\n component: CategoryNewPage\r\n },\r\n {\r\n path: 'item',\r\n loadChildren: () => import('../../item/item.module').then( m => m.ItemPageModule)\r\n }\r\n];\r\n\r\n@NgModule({\r\n imports: [RouterModule.forChild(routes)],\r\n exports: [RouterModule],\r\n})\r\nexport class CategoryNewPageRoutingModule {}\r\n","import { NgModule } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { FormsModule } from '@angular/forms';\r\n\r\nimport { IonicModule } from '@ionic/angular';\r\n\r\nimport { CategoryNewPageRoutingModule } from './category-new-routing.module';\r\n\r\nimport { CategoryNewPage } from './category-new.page';\r\nimport { SharedModule } from '../../../shared/shared.module';\r\n\r\n@NgModule({\r\n imports: [\r\n CommonModule,\r\n FormsModule,\r\n IonicModule,\r\n CategoryNewPageRoutingModule,\r\n SharedModule\r\n ],\r\n declarations: [CategoryNewPage]\r\n})\r\nexport class CategoryNewPageModule {}\r\n","export default \"#logo-toolbar {\\n max-height: 10vh;\\n}\\n\\n.produto-image {\\n background-position: center center;\\n width: 100%;\\n height: 100%;\\n background-size: 110% 110%;\\n}\\n\\n.produto-image.shrink-animation {\\n /* Safari 4+ */\\n /* Fx 5+ */\\n /* Opera 12+ */\\n animation: shrink 5s infinite;\\n /* IE 10+, Fx 29+ */\\n}\\n\\n.produto-image.shrink-animation-delay {\\n /* Safari 4+ */\\n /* Fx 5+ */\\n /* Opera 12+ */\\n animation: shrink 5s 2s infinite;\\n /* IE 10+, Fx 29+ */\\n}\\n\\n@keyframes shrink {\\n 20% {\\n transform: scale(1, 1);\\n }\\n 60% {\\n transform: scale(1.2, 1.2);\\n }\\n 100% {\\n transform: scale(1, 1);\\n }\\n}\\n\\n.img-wrapper {\\n display: inline-block;\\n /* change the default display type to inline-block */\\n overflow: hidden;\\n /* hide the overflow */\\n width: 100%;\\n height: 50%;\\n}\\n\\n.fav-icon {\\n color: var(--ion-color-primary);\\n cursor: pointer;\\n}\\n\\n.search-input {\\n background-color: var(--ion-color-search-button);\\n height: 100%;\\n border-radius: 3px;\\n opacity: 0;\\n position: absolute;\\n width: 0;\\n transition-duration: 0.4s;\\n top: 0;\\n}\\n\\n.search-input.showing {\\n opacity: 1;\\n width: 70vw;\\n max-width: initial;\\n}\\n\\nion-content {\\n overflow-x: scroll;\\n}\\n\\n.board-button {\\n --padding-start: 0;\\n --padding-end: 0;\\n}\\n\\nion-segment-button {\\n height: 35px;\\n min-height: 35px;\\n --color-checked: var(--ion-color-dark);\\n}\\n\\n.cart-icon {\\n font-size: min(24px, 4vw);\\n}\\n/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNyYy9hcHAvcGFnZXMvaG9tZS9jYXRlZ29yeS1uZXcvQzpcXFVzZXJzXFxVc2VyXFxEZXNrdG9wXFxQcm9qZXRvc1xcSW9uaWNcXFppbW1lci9zcmNcXGFwcFxccGFnZXNcXGhvbWVcXGNhdGVnb3J5LW5ld1xcY2F0ZWdvcnktbmV3LnBhZ2Uuc2NzcyIsInNyYy9hcHAvcGFnZXMvaG9tZS9jYXRlZ29yeS1uZXcvY2F0ZWdvcnktbmV3LnBhZ2Uuc2NzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtFQUNJLGdCQUFBO0FDQ0o7O0FERUE7RUFDSSxrQ0FBQTtFQUNBLFdBQUE7RUFDQSxZQUFBO0VBQ0EsMEJBQUE7QUNDSjs7QURFQTtFQUMyQyxjQUFBO0VBQ0gsVUFBQTtFQUNGLGNBQUE7RUFDbEMsNkJBQUE7RUFBK0IsbUJBQUE7QUNLbkM7O0FERkE7RUFDMkMsY0FBQTtFQUNILFVBQUE7RUFDRixjQUFBO0VBQ2xDLGdDQUFBO0VBQWtDLG1CQUFBO0FDU3RDOztBRE5BO0VBQ0k7SUFDSSxzQkFBQTtFQ1NOO0VEUEU7SUFDSSwwQkFBQTtFQ1NOO0VEUEU7SUFDSSxzQkFBQTtFQ1NOO0FBQ0Y7O0FETkE7RUFDSSxxQkFBQTtFQUF1QixvREFBQTtFQUN2QixnQkFBQTtFQUF1QixzQkFBQTtFQUN2QixXQUFBO0VBQ0EsV0FBQTtBQ1VKOztBRFBBO0VBQ0ksK0JBQUE7RUFDQSxlQUFBO0FDVUo7O0FEUEE7RUFDSSxnREFBQTtFQUNBLFlBQUE7RUFDQSxrQkFBQTtFQUNBLFVBQUE7RUFDQSxrQkFBQTtFQUNBLFFBQUE7RUFDQSx5QkFBQTtFQUNBLE1BQUE7QUNVSjs7QURQQTtFQUNJLFVBQUE7RUFDQSxXQUFBO0VBQ0Esa0JBQUE7QUNVSjs7QURQQTtFQUNJLGtCQUFBO0FDVUo7O0FEUEE7RUFDSSxrQkFBQTtFQUNBLGdCQUFBO0FDVUo7O0FEUEE7RUFDSSxZQUFBO0VBQ0EsZ0JBQUE7RUFDQSxzQ0FBQTtBQ1VKOztBRFBBO0VBQ0kseUJBQUE7QUNVSiIsImZpbGUiOiJzcmMvYXBwL3BhZ2VzL2hvbWUvY2F0ZWdvcnktbmV3L2NhdGVnb3J5LW5ldy5wYWdlLnNjc3MiLCJzb3VyY2VzQ29udGVudCI6WyIjbG9nby10b29sYmFyIHtcclxuICAgIG1heC1oZWlnaHQ6IDEwdmg7XHJcbn1cclxuXHJcbi5wcm9kdXRvLWltYWdlIHtcclxuICAgIGJhY2tncm91bmQtcG9zaXRpb246IGNlbnRlciBjZW50ZXI7XHJcbiAgICB3aWR0aDogMTAwJTtcclxuICAgIGhlaWdodDogMTAwJTtcclxuICAgIGJhY2tncm91bmQtc2l6ZTogMTEwJSAxMTAlO1xyXG59XHJcblxyXG4ucHJvZHV0by1pbWFnZS5zaHJpbmstYW5pbWF0aW9uIHtcclxuICAgIC13ZWJraXQtYW5pbWF0aW9uOiBzaHJpbmsgNXMgaW5maW5pdGU7IC8qIFNhZmFyaSA0KyAqL1xyXG4gICAgLW1vei1hbmltYXRpb246IHNocmluayA1cyBpbmZpbml0ZTsgLyogRnggNSsgKi9cclxuICAgIC1vLWFuaW1hdGlvbjogc2hyaW5rIDVzIGluZmluaXRlOyAvKiBPcGVyYSAxMisgKi9cclxuICAgIGFuaW1hdGlvbjogc2hyaW5rIDVzIGluZmluaXRlOyAvKiBJRSAxMCssIEZ4IDI5KyAqL1xyXG59XHJcblxyXG4ucHJvZHV0by1pbWFnZS5zaHJpbmstYW5pbWF0aW9uLWRlbGF5IHtcclxuICAgIC13ZWJraXQtYW5pbWF0aW9uOiBzaHJpbmsgNXMgaW5maW5pdGU7IC8qIFNhZmFyaSA0KyAqL1xyXG4gICAgLW1vei1hbmltYXRpb246IHNocmluayA1cyBpbmZpbml0ZTsgLyogRnggNSsgKi9cclxuICAgIC1vLWFuaW1hdGlvbjogc2hyaW5rIDVzIGluZmluaXRlOyAvKiBPcGVyYSAxMisgKi9cclxuICAgIGFuaW1hdGlvbjogc2hyaW5rIDVzIDJzIGluZmluaXRlOyAvKiBJRSAxMCssIEZ4IDI5KyAqL1xyXG59XHJcblxyXG5Aa2V5ZnJhbWVzIHNocmluayB7XHJcbiAgICAyMCUge1xyXG4gICAgICAgIHRyYW5zZm9ybTogc2NhbGUoMSwgMSk7XHJcbiAgICB9XHJcbiAgICA2MCUge1xyXG4gICAgICAgIHRyYW5zZm9ybTogc2NhbGUoMS4yLCAxLjIpO1xyXG4gICAgfVxyXG4gICAgMTAwJSB7XHJcbiAgICAgICAgdHJhbnNmb3JtOiBzY2FsZSgxLCAxKTtcclxuICAgIH1cclxufVxyXG5cclxuLmltZy13cmFwcGVyIHtcclxuICAgIGRpc3BsYXk6IGlubGluZS1ibG9jazsgLyogY2hhbmdlIHRoZSBkZWZhdWx0IGRpc3BsYXkgdHlwZSB0byBpbmxpbmUtYmxvY2sgKi9cclxuICAgIG92ZXJmbG93OiBoaWRkZW47ICAgICAgLyogaGlkZSB0aGUgb3ZlcmZsb3cgKi9cclxuICAgIHdpZHRoOiAxMDAlO1xyXG4gICAgaGVpZ2h0OiA1MCU7XHJcbn1cclxuXHJcbi5mYXYtaWNvbiB7XHJcbiAgICBjb2xvcjogdmFyKC0taW9uLWNvbG9yLXByaW1hcnkpO1xyXG4gICAgY3Vyc29yOiBwb2ludGVyO1xyXG59XHJcblxyXG4uc2VhcmNoLWlucHV0IHtcclxuICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLWlvbi1jb2xvci1zZWFyY2gtYnV0dG9uKTtcclxuICAgIGhlaWdodDogMTAwJTtcclxuICAgIGJvcmRlci1yYWRpdXM6IDNweDtcclxuICAgIG9wYWNpdHk6IDA7XHJcbiAgICBwb3NpdGlvbjogYWJzb2x1dGU7XHJcbiAgICB3aWR0aDogMDtcclxuICAgIHRyYW5zaXRpb24tZHVyYXRpb246IC40cztcclxuICAgIHRvcDogMDtcclxufVxyXG5cclxuLnNlYXJjaC1pbnB1dC5zaG93aW5nIHtcclxuICAgIG9wYWNpdHk6IDE7XHJcbiAgICB3aWR0aDogNzB2dztcclxuICAgIG1heC13aWR0aDogaW5pdGlhbDtcclxufVxyXG5cclxuaW9uLWNvbnRlbnQge1xyXG4gICAgb3ZlcmZsb3cteDogc2Nyb2xsO1xyXG59XHJcblxyXG4uYm9hcmQtYnV0dG9uIHtcclxuICAgIC0tcGFkZGluZy1zdGFydDogMDtcclxuICAgIC0tcGFkZGluZy1lbmQ6IDA7XHJcbn1cclxuXHJcbmlvbi1zZWdtZW50LWJ1dHRvbiB7XHJcbiAgICBoZWlnaHQ6IDM1cHg7XHJcbiAgICBtaW4taGVpZ2h0OiAzNXB4O1xyXG4gICAgLS1jb2xvci1jaGVja2VkOiB2YXIoLS1pb24tY29sb3ItZGFyayk7XHJcbn1cclxuXHJcbi5jYXJ0LWljb24ge1xyXG4gICAgZm9udC1zaXplOiBtaW4oMjRweCwgNHZ3KVxyXG59IiwiI2xvZ28tdG9vbGJhciB7XG4gIG1heC1oZWlnaHQ6IDEwdmg7XG59XG5cbi5wcm9kdXRvLWltYWdlIHtcbiAgYmFja2dyb3VuZC1wb3NpdGlvbjogY2VudGVyIGNlbnRlcjtcbiAgd2lkdGg6IDEwMCU7XG4gIGhlaWdodDogMTAwJTtcbiAgYmFja2dyb3VuZC1zaXplOiAxMTAlIDExMCU7XG59XG5cbi5wcm9kdXRvLWltYWdlLnNocmluay1hbmltYXRpb24ge1xuICAtd2Via2l0LWFuaW1hdGlvbjogc2hyaW5rIDVzIGluZmluaXRlO1xuICAvKiBTYWZhcmkgNCsgKi9cbiAgLW1vei1hbmltYXRpb246IHNocmluayA1cyBpbmZpbml0ZTtcbiAgLyogRnggNSsgKi9cbiAgLW8tYW5pbWF0aW9uOiBzaHJpbmsgNXMgaW5maW5pdGU7XG4gIC8qIE9wZXJhIDEyKyAqL1xuICBhbmltYXRpb246IHNocmluayA1cyBpbmZpbml0ZTtcbiAgLyogSUUgMTArLCBGeCAyOSsgKi9cbn1cblxuLnByb2R1dG8taW1hZ2Uuc2hyaW5rLWFuaW1hdGlvbi1kZWxheSB7XG4gIC13ZWJraXQtYW5pbWF0aW9uOiBzaHJpbmsgNXMgaW5maW5pdGU7XG4gIC8qIFNhZmFyaSA0KyAqL1xuICAtbW96LWFuaW1hdGlvbjogc2hyaW5rIDVzIGluZmluaXRlO1xuICAvKiBGeCA1KyAqL1xuICAtby1hbmltYXRpb246IHNocmluayA1cyBpbmZpbml0ZTtcbiAgLyogT3BlcmEgMTIrICovXG4gIGFuaW1hdGlvbjogc2hyaW5rIDVzIDJzIGluZmluaXRlO1xuICAvKiBJRSAxMCssIEZ4IDI5KyAqL1xufVxuXG5Aa2V5ZnJhbWVzIHNocmluayB7XG4gIDIwJSB7XG4gICAgdHJhbnNmb3JtOiBzY2FsZSgxLCAxKTtcbiAgfVxuICA2MCUge1xuICAgIHRyYW5zZm9ybTogc2NhbGUoMS4yLCAxLjIpO1xuICB9XG4gIDEwMCUge1xuICAgIHRyYW5zZm9ybTogc2NhbGUoMSwgMSk7XG4gIH1cbn1cbi5pbWctd3JhcHBlciB7XG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgLyogY2hhbmdlIHRoZSBkZWZhdWx0IGRpc3BsYXkgdHlwZSB0byBpbmxpbmUtYmxvY2sgKi9cbiAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgLyogaGlkZSB0aGUgb3ZlcmZsb3cgKi9cbiAgd2lkdGg6IDEwMCU7XG4gIGhlaWdodDogNTAlO1xufVxuXG4uZmF2LWljb24ge1xuICBjb2xvcjogdmFyKC0taW9uLWNvbG9yLXByaW1hcnkpO1xuICBjdXJzb3I6IHBvaW50ZXI7XG59XG5cbi5zZWFyY2gtaW5wdXQge1xuICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1pb24tY29sb3Itc2VhcmNoLWJ1dHRvbik7XG4gIGhlaWdodDogMTAwJTtcbiAgYm9yZGVyLXJhZGl1czogM3B4O1xuICBvcGFjaXR5OiAwO1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHdpZHRoOiAwO1xuICB0cmFuc2l0aW9uLWR1cmF0aW9uOiAwLjRzO1xuICB0b3A6IDA7XG59XG5cbi5zZWFyY2gtaW5wdXQuc2hvd2luZyB7XG4gIG9wYWNpdHk6IDE7XG4gIHdpZHRoOiA3MHZ3O1xuICBtYXgtd2lkdGg6IGluaXRpYWw7XG59XG5cbmlvbi1jb250ZW50IHtcbiAgb3ZlcmZsb3cteDogc2Nyb2xsO1xufVxuXG4uYm9hcmQtYnV0dG9uIHtcbiAgLS1wYWRkaW5nLXN0YXJ0OiAwO1xuICAtLXBhZGRpbmctZW5kOiAwO1xufVxuXG5pb24tc2VnbWVudC1idXR0b24ge1xuICBoZWlnaHQ6IDM1cHg7XG4gIG1pbi1oZWlnaHQ6IDM1cHg7XG4gIC0tY29sb3ItY2hlY2tlZDogdmFyKC0taW9uLWNvbG9yLWRhcmspO1xufVxuXG4uY2FydC1pY29uIHtcbiAgZm9udC1zaXplOiBtaW4oMjRweCwgNHZ3KTtcbn0iXX0= */\";","import { Component, OnInit } from \"@angular/core\";\r\nimport { Router } from \"@angular/router\";\r\nimport { of, Subscription } from \"rxjs\";\r\n\r\nimport {\r\n IonContent,\r\n IonSegmentButton,\r\n IonSegment,\r\n AlertController,\r\n ModalController,\r\n IonInput,\r\n} from \"@ionic/angular\";\r\n\r\nimport { AppComponent } from \"../../../app.component\";\r\nimport { AuthService } from \"../../../shared/auth.service\";\r\nimport { CartService } from \"../../../services/cart.service\";\r\nimport { Category } from \"../../../interfaces/category.interface\";\r\nimport { CategoryService } from \"../../../services/category.service\";\r\nimport { ItemPage } from \"../../item/item.page\";\r\nimport { Product } from \"../../../models/produto.model\";\r\nimport { ProductService } from \"../../../services/product.service\";\r\nimport { RestaurantService } from \"../../../services/restaurant.service\";\r\nimport { StorageService } from \"../../../services/storage.service\";\r\nimport { Utils } from \"../../../shared/util\";\r\nimport { ZimmerStorage } from \"../../../models/zimmerStorage.model\";\r\nimport { QrcodeService } from \"src/app/services/qrcode.service\";\r\nimport { environment } from \"src/environments/environment\";\r\n\r\ndeclare var Html5Qrcode;\r\n\r\n@Component({\r\n selector: \"app-category-new\",\r\n templateUrl: \"./category-new.page.html\",\r\n styleUrls: [\"./category-new.page.scss\"],\r\n})\r\nexport class CategoryNewPage implements OnInit {\r\n /**\r\n * Todas as categorias do restaurante\r\n */\r\n categories: Category[] = [];\r\n /**\r\n * Index de qual categoria está em relação ao label, não ao segment. O index é usado no array categoryLenghts\r\n */\r\n indexOfCategory: number = 1;\r\n /**\r\n * Index de rolagem. A cada rolagem no final da tela ou próximo dela, será somado + 1\r\n */\r\n indexVisibleProduct: number = 0;\r\n /**\r\n * Categorias a serem mostradas durante a rolagem\r\n */\r\n categoryLengths: Category[] = [];\r\n /**\r\n * Todos os produtos do restaurante\r\n */\r\n products: Product[] = [];\r\n /**\r\n * Produtos visíveis\r\n */\r\n visibleProducts: Product[] = [];\r\n /**\r\n * Diz se foi uma ação clicando em uma das categorias. Se não, apenas rolagem. É usado na função onScroll\r\n */\r\n clickAction: boolean;\r\n /**\r\n * String mostrada antes do menu de restaurante\r\n */\r\n greetings: string;\r\n /**\r\n * Título mostrado\r\n */\r\n title: string;\r\n /**\r\n * Url base\r\n */\r\n baseUrl: string; // TODO revisar necessidade\r\n\r\n constructor(\r\n private alertCtrl: AlertController,\r\n public auth: AuthService,\r\n private appComponent: AppComponent,\r\n public cart: CartService,\r\n private categoryService: CategoryService,\r\n private modalCtrl: ModalController,\r\n private productService: ProductService,\r\n private restaurantService: RestaurantService,\r\n private router: Router,\r\n private storage: StorageService,\r\n public utils: Utils,\r\n private qrCodeScanner: QrcodeService\r\n ) {}\r\n\r\n ngOnInit(): void {\r\n const cnpj = this.storage.get(\"cnpj\");\r\n this.setCustomVars();\r\n const restaurante = this.restaurantService.getRestaurant();\r\n\r\n if (restaurante) {\r\n this.loadProducts().add(() => {\r\n this.showMoreProducts();\r\n });\r\n } else {\r\n this.restaurantService.getByCnpj(cnpj).subscribe((restaurant) => {\r\n this.restaurantService.setRestaurant(restaurant);\r\n this.loadProducts().add(() => {\r\n this.showMoreProducts();\r\n });\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Seta as variáveis customizáveis\r\n */\r\n setCustomVars(): void {\r\n const restaurante = this.restaurantService.getRestaurant();\r\n this.title = restaurante?.nome;\r\n this.greetings = restaurante?.zimmer;\r\n }\r\n\r\n /**\r\n * Retorna uma isncrição depois de popular a variável categories com as categorias salvas em serviço ou requisitadas na API\r\n */\r\n loadProducts(): Subscription {\r\n const categories = this.categoryService.getCategories();\r\n\r\n return categories.length > 0\r\n ? of(this.categoryService.getCategories()).subscribe((categories) => {\r\n const produtos: Product[] = [];\r\n\r\n categories.forEach((category) => {\r\n produtos.push(...category.produtos);\r\n this.categoryLengths[category.categoriaId] = category;\r\n });\r\n this.categories = categories;\r\n this.products = produtos;\r\n })\r\n : this.productService.getAll().subscribe((r) => {\r\n const result: any[] = (r as any).results;\r\n const produtos: Product[] = [];\r\n\r\n const categories = result.map((v) => {\r\n let category: Category = new Object() as Category;\r\n const keys = Object.keys(v.categoria);\r\n keys.forEach((key) => {\r\n category[key] = v.categoria[key];\r\n });\r\n category.produtos = v.produtos;\r\n produtos.push(...v.produtos);\r\n this.categoryLengths[category.categoriaId] = category;\r\n return category;\r\n });\r\n\r\n this.categories = categories;\r\n\r\n this.products = produtos;\r\n\r\n this.categoryService.setCategories(categories);\r\n });\r\n }\r\n\r\n /**\r\n * fnção chamada durante a rolagem do IonContent\r\n */\r\n onScroll(content: IonContent): void {\r\n const fisrtProdutoItem: HTMLElement = document.getElementById(\r\n \"produto-item-\" + this.visibleProducts[0].produtoId\r\n ); // Elemento do primeiro produto de todos\r\n const firstProdutoItemOnScreen: boolean =\r\n this.utils.isOnScreen(fisrtProdutoItem); // Primeiro produto está na tela?\r\n const segment: IonSegment = document.getElementById(\r\n \"segment-category\"\r\n ) as any as IonSegment; // Barra horizontal de categorias\r\n let categoryId = this.categories[0].categoriaId; // Categoria a ser selecionada - Por padrão, a primeira da lista\r\n\r\n // Se o primeiro produto está na tela\r\n if (firstProdutoItemOnScreen) {\r\n // O valor da barra de categorias recebe o valor do botão correspondente ao da categoria do primeiro produto\r\n segment.value = \"segment-button-\" + this.visibleProducts[0].categoriaId;\r\n // Pega o botão da categoria que será selecionada\r\n const button = document.getElementById(\r\n \"segment-button-\" + categoryId\r\n ) as any as IonSegmentButton;\r\n // Rola até ele\r\n (segment as any as HTMLElement).scrollTo({\r\n left: button[\"offsetLeft\"] - 30,\r\n behavior: \"smooth\",\r\n });\r\n segment.value = \"segment-button-\" + categoryId;\r\n // Se não, se não for um clique no botão de categoria\r\n } else if (!this.clickAction) {\r\n // Pega o scroll do IonContent\r\n content.getScrollElement().then((scroll) => {\r\n const scrollTop = scroll.scrollTop; // Scroll atual do IonContent\r\n\r\n if (scrollTop) {\r\n const totalScroll = scroll.scrollHeight - scroll.offsetHeight; // Calcula o scroll restante (scrollDisponível - ScrollJáRolado)\r\n\r\n // Dou reverse no array para que procure primeiro pelos últimos - Não passa por todos novamente (mais rápido).\r\n // Uso o spreadOperator para que o array principal não seja afetado.\r\n for (const product of [...this.visibleProducts].reverse()) {\r\n const element = document.getElementById(\r\n \"produto-item-\" + product.produtoId\r\n );\r\n const isOnScreen = this.utils.isOnScreen(element);\r\n // console.log(product, isOnScreen, 'produto está na tela?')\r\n\r\n // Se o elemento estiver na tela, a categoria a ser selecionada será essa\r\n if (isOnScreen) {\r\n categoryId = product.categoriaId;\r\n // Para o loop\r\n break;\r\n }\r\n }\r\n\r\n // Se o total a ser rolado for <= à rolagem atual E contador de\r\n // rolagens(indexVisibleProduct) * 15 <= que o tamanho do array de produtos visíveis\r\n if (\r\n totalScroll <= scrollTop + 200 &&\r\n this.indexVisibleProduct * 15 <= this.visibleProducts.length\r\n ) {\r\n this.indexVisibleProduct++; // Adiciona + 1 no contador de rolagens\r\n this.showMoreProducts(); // Adiciona mais produtos no array de produtos visíveis\r\n }\r\n }\r\n // Rola e seleciona para a categoria de produtos escolhida\r\n const button = document.getElementById(\r\n \"segment-button-\" + categoryId\r\n ) as any as IonSegmentButton;\r\n (segment as any as HTMLElement).scrollTo({\r\n left: button[\"offsetLeft\"] - 30,\r\n behavior: \"smooth\",\r\n });\r\n segment.value = \"segment-button-\" + categoryId;\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Adiciona mais produtos nos produtos visíveis (geralmente + 15). Número de rolagens * 15\r\n */\r\n showMoreProducts(): void {\r\n this.visibleProducts = [...this.products].splice(\r\n 0,\r\n ++this.indexVisibleProduct * 15\r\n );\r\n }\r\n\r\n /**\r\n * Checa se este é o primeiro produto de uma lista de categorias. Caso sim, será exibido um label com o nome da categoria acimma dele\r\n */\r\n showCategoryLabel(product: Product, i: number): boolean {\r\n if (product.categoriaId != this.products[i - 1]?.categoriaId) {\r\n this.indexOfCategory++;\r\n return true;\r\n } else return false;\r\n }\r\n\r\n /**\r\n * Rola a tela até que chegue no primeiro do produto da categoria selecionada\r\n * @param { number } categoryId\r\n */\r\n scrollToCategory(categoryId: number): void {\r\n // Diz que a ação de scroll é realizada por um click na barra de categorias\r\n this.clickAction = true;\r\n // Procura o index do primeiro produto da categoria selecionada na lista de produtos visíveis (retorna -1 caso não ache)\r\n let indexFirstProductOfCategory = this.visibleProducts.findIndex(\r\n (product) => product.categoriaId == categoryId\r\n );\r\n\r\n // Enquanto não achar\r\n while (indexFirstProductOfCategory == -1) {\r\n // Adiciona mais produtos à lista de produtos visíveis\r\n this.showMoreProducts();\r\n // Procura o index do primeiro produto da categoria selecionada na lista de produtos visíveis (retorna -1 caso não ache)\r\n indexFirstProductOfCategory = this.visibleProducts.findIndex(\r\n (product) => product.categoriaId == categoryId\r\n );\r\n }\r\n\r\n // Timeout é pra que sejam renderizado os produtos na tela antes de fazer a busca.\r\n // O tempo de espera é 0 porque o fato de o setTimeout ser assíncrono já é o suficiente\r\n // para que ele processe a página antes desse bloco de comando\r\n setTimeout(() => {\r\n // Procura o elemento HTML do card do produto\r\n const produtoItem = document.getElementById(\r\n \"produto-item-\" +\r\n this.visibleProducts[indexFirstProductOfCategory].produtoId\r\n );\r\n // Busca o IonContent que será scrollado\r\n const content = document.getElementById(\r\n \"ion-content-products\"\r\n ) as any as IonContent;\r\n // Por causa de diferenças no design, se o card foor do tipo 1, ele tem que pegar o offsetTop do elemento pai.\r\n // Se não, o dele mesmo. Para QUALQUER alteração no design da página deve ser feita a revisão da funcionalidade de scroll\r\n const offsetTop =\r\n produtoItem.classList[0] == \"style-1\"\r\n ? produtoItem.parentElement.offsetTop\r\n : produtoItem.offsetTop;\r\n\r\n content.getScrollElement().then((scroll) => {\r\n scroll.scrollTo({\r\n behavior: \"smooth\",\r\n top: offsetTop,\r\n });\r\n // Para que seja scrollado depois sem ser pelo click, tem que passar a variável pra false. NÃO ESQUEÇA\r\n this.clickAction = false;\r\n });\r\n }, 0);\r\n }\r\n\r\n /**\r\n * Abre o modal com o carrinho\r\n */\r\n openCart(): void {\r\n const items = this.cart.getAllItems();\r\n this.cart.showCart(items);\r\n }\r\n\r\n /**\r\n * Fecha o modal atual (esta Page caso ela esteja aberta em forma de modal)\r\n */\r\n closeModals(): void {\r\n this.modalCtrl.dismiss();\r\n }\r\n\r\n /**\r\n * Mostra os detalhes do item selecionado em forma de modal\r\n * @param prod\r\n */\r\n showItemDetails(prod: Product): void {\r\n this.modalCtrl\r\n .create({\r\n component: ItemPage,\r\n componentProps: {\r\n openCartFn: this.openCart,\r\n prod,\r\n },\r\n cssClass: \"modal-fullscreen\",\r\n })\r\n .then((modal) => modal.present());\r\n }\r\n\r\n /**\r\n * Procura um produto com o nome digitado\r\n * @param value\r\n */\r\n searchProd(value: string | number): void {\r\n if ((value + \"\").length > 0)\r\n this.visibleProducts = this.products.filter((prod) =>\r\n prod.nome.toLowerCase().includes((value + \"\").toLowerCase())\r\n );\r\n else\r\n this.visibleProducts = this.products.filter((prod) =>\r\n prod.nome.toLowerCase().includes((value + \"\").toLowerCase())\r\n );\r\n }\r\n\r\n /**\r\n * Toggle da classe showing no input selecionado (evento específico do DOM)\r\n * @param searchInput Input a ser manipulado\r\n */\r\n searchButtonClick(searchInput: IonInput): void {\r\n searchInput[\"el\"].className = !searchInput[\"el\"].className.includes(\r\n \"showing\"\r\n )\r\n ? searchInput[\"el\"].className + \" showing\"\r\n : searchInput[\"el\"].className.replace(\"showing\", \"\");\r\n searchInput.setFocus();\r\n }\r\n\r\n /**\r\n * Evento **blur** do elemento selecionado (evento específico do DOM)\r\n * @param searchInput\r\n */\r\n searchBarInputBlur(searchInput: IonInput): void {\r\n searchInput.value?.toString().length == 0\r\n ? (searchInput[\"el\"].className = searchInput[\"el\"].className.replace(\r\n \"showing\",\r\n \"\"\r\n ))\r\n : false;\r\n }\r\n\r\n /**\r\n * Troca de mesa\r\n */\r\n changeTableClick(): void {\r\n const type = this.storage.get(\"type\");\r\n if (type == \"qrcode\")\r\n this.utils.scanQr().then((result) => {\r\n const results = result.text.split(\"qrcode/\")[1].split(\"/\");\r\n const table = results[1];\r\n this.auth.changeTable(Number(table));\r\n });\r\n else this.setTable();\r\n }\r\n\r\n /**\r\n * Chama a câmera para escanear o QRCode\r\n */\r\n scan(): void {\r\n this.utils\r\n .scanQr()\r\n .then((result) => {\r\n const results = result.text.split(\"qrcode/\")[1].split(\"/\");\r\n const cnpj = results[0];\r\n const table = results[1];\r\n const zimmer = new Object() as ZimmerStorage;\r\n zimmer.cnpj = cnpj;\r\n zimmer.tableNumber = Number(table);\r\n zimmer.mode = environment.appModes.table as\r\n | \"zap\"\r\n | \"qrcode\"\r\n | \"ficha\"\r\n | \"menu\"\r\n | \"pedido\"\r\n | \"gestor\";\r\n this.storage.prepare(zimmer);\r\n\r\n // this.router.navigate([cnpj])\r\n this.router.navigate([zimmer.cnpj]);\r\n return true;\r\n })\r\n .catch((error) => {\r\n this.alertCtrl\r\n .create({\r\n header: \"Error scanner\",\r\n message: JSON.stringify(error),\r\n })\r\n .then((alert) => alert.present());\r\n return false;\r\n });\r\n }\r\n\r\n /**\r\n * Mostra o alert para setar o número de uma mesa no storage\r\n */\r\n setTable(): void {\r\n const type: \"qrcode\" | \"credetials\" = this.storage.get(\"type\");\r\n this.auth.setTable();\r\n }\r\n\r\n /**\r\n * Verifica o estilo em que será mostrados os produtos\r\n */\r\n checkItemStyle(): string | number {\r\n return this.categoryService.checkItemStyle();\r\n }\r\n\r\n /**\r\n * Busca o ID do pedido salvo no SessionStorage\r\n */\r\n getPedidoId(): string | number {\r\n return this.cart.getPedidoIdInSession();\r\n }\r\n\r\n // testCam() {\r\n // Html5Qrcode.getCameras().then(devices => { // TODO Fazer pra procurar facing back e facing front (pra garantir que procure pela traseira, até então, os últimos índices do array são back)\r\n // document.getElementById('teste-cam').innerHTML = (devices.map((device, index) => `device ${index} ${JSON.stringify(devices[index])} `) as []).join('')\r\n // // setTimeout(() => {\r\n // // const cam = new Html5Qrcode('teste-cam')\r\n // // cam.start(devices[1]?.id || devices[0]?.id, { fps: 1 }, text => console.log(text), error => console.log(error)).catch(err => console.log('deu pra abrir nao'))\r\n // // }, 100000)\r\n // })\r\n // this.qrCodeScanner.scan({\r\n // side: 'back',\r\n // useNativePlugin: false\r\n // })\r\n // }\r\n}\r\n"],"sourceRoot":"webpack:///"}