diff --git a/cypress/integration/dashboard.spec.ts b/cypress/integration/dashboard.spec.ts index 97a3b579..1a8868e2 100644 --- a/cypress/integration/dashboard.spec.ts +++ b/cypress/integration/dashboard.spec.ts @@ -168,25 +168,13 @@ describe('dashboard', async function () { // }); describe('search section', function () { - it('should lead to the search when hitting enter', function () { + it('should go to search', function () { cy.visit('/overview'); - cy.get('stapps-search-section') - .find('.searchbar') - .type('test', {scrollBehavior: false}) - .type('{enter}', {scrollBehavior: false}); - cy.url().should('eq', Cypress.config().baseUrl + '/search?query=test'); - cy.get('ion-searchbar').should('have.value', 'test'); - - cy.get('stapps-data-list-item').should('have.length.greaterThan', 0); - }); - - it('should go to search when clicking the icon', function () { - cy.visit('/overview'); - - cy.get('stapps-search-section').find('ion-icon[name=search]').click({force: true}); - cy.url().should('eq', Cypress.config().baseUrl + '/search?query='); + cy.get('ion-searchbar').click({scrollBehavior: 'center'}); + cy.url().should('eq', Cypress.config().baseUrl + '/search'); cy.get('ion-searchbar').should('not.have.value'); + cy.get('ion-searchbar input.searchbar-input').should('have.focus'); cy.get('stapps-data-list-item').should('have.length', 0); }); diff --git a/src/app/modules/dashboard/dashboard.component.html b/src/app/modules/dashboard/dashboard.component.html index 1ae3cb05..98c1c61f 100644 --- a/src/app/modules/dashboard/dashboard.component.html +++ b/src/app/modules/dashboard/dashboard.component.html @@ -43,7 +43,7 @@ - + diff --git a/src/app/modules/dashboard/dashboard.component.ts b/src/app/modules/dashboard/dashboard.component.ts index dfd8c3a0..e4fe0f3d 100644 --- a/src/app/modules/dashboard/dashboard.component.ts +++ b/src/app/modules/dashboard/dashboard.component.ts @@ -43,8 +43,6 @@ export class DashboardComponent implements OnInit, OnDestroy { @ViewChild('schedule', {read: ElementRef}) scheduleRef: ElementRef; - @ViewChild('search', {read: ElementRef}) searchRef: ElementRef; - @ViewChild('ionContent') ionContentRef: IonContent; collapseAnimation: DashboardCollapse; @@ -145,8 +143,4 @@ export class DashboardComponent implements OnInit, OnDestroy { this._eventUuidSubscription.unsubscribe(); this.collapseAnimation.destroy(); } - - async onSearchBarFocus(_event: Event) { - this.ionContentRef.scrollToTop(100); - } } diff --git a/src/app/modules/dashboard/dashboard.module.ts b/src/app/modules/dashboard/dashboard.module.ts index b1b10e79..66919a61 100644 --- a/src/app/modules/dashboard/dashboard.module.ts +++ b/src/app/modules/dashboard/dashboard.module.ts @@ -24,8 +24,6 @@ import {DataModule} from '../data/data.module'; import {SettingsProvider} from '../settings/settings.provider'; import {DashboardComponent} from './dashboard.component'; import {EditModalComponent} from './edit-modal/edit-modal.component'; -import {SectionComponent} from './section/section.component'; -import {NavigationSectionComponent} from './sections/navigation-section/navigation-section.component'; import {SearchSectionComponent} from './sections/search-section/search-section.component'; import {NewsSectionComponent} from './sections/news-section/news-section.component'; import {MensaSectionComponent} from './sections/mensa-section/mensa-section.component'; @@ -48,9 +46,7 @@ const catalogRoutes: Routes = [ */ @NgModule({ declarations: [ - SectionComponent, EditModalComponent, - NavigationSectionComponent, SearchSectionComponent, NewsSectionComponent, MensaSectionComponent, diff --git a/src/app/modules/dashboard/sections/favorites-section/favorites-section.component.html b/src/app/modules/dashboard/sections/favorites-section/favorites-section.component.html index bcae0574..33592964 100644 --- a/src/app/modules/dashboard/sections/favorites-section/favorites-section.component.html +++ b/src/app/modules/dashboard/sections/favorites-section/favorites-section.component.html @@ -13,11 +13,10 @@ ~ this program. If not, see . --> - + + + + {{ 'dashboard.favorites.no_favorite_prefix' | translate }} - {{ 'dashboard.favorites.no_favorite_link' | translate }} + {{ 'dashboard.favorites.no_favorite_link' | translate }} {{ 'dashboard.favorites.no_favorite_suffix' | translate }} diff --git a/src/app/modules/dashboard/sections/favorites-section/favorites-section.component.ts b/src/app/modules/dashboard/sections/favorites-section/favorites-section.component.ts index 7e885c73..72eaef6d 100644 --- a/src/app/modules/dashboard/sections/favorites-section/favorites-section.component.ts +++ b/src/app/modules/dashboard/sections/favorites-section/favorites-section.component.ts @@ -127,11 +127,4 @@ export class FavoritesSectionComponent extends SearchPageComponent implements On notifySelect(item: SCThings) { this.dataRoutingService.emitChildEvent(item); } - - /** - * Action when user clicked edit to this section - */ - onSectionEdit() { - void this.router.navigate(['/search']); - } } diff --git a/src/app/modules/dashboard/sections/mensa-section/mensa-section.component.html b/src/app/modules/dashboard/sections/mensa-section/mensa-section.component.html index aec61fbf..a8bfd224 100644 --- a/src/app/modules/dashboard/sections/mensa-section/mensa-section.component.html +++ b/src/app/modules/dashboard/sections/mensa-section/mensa-section.component.html @@ -16,24 +16,17 @@ - + + + + - + {{ 'dashboard.canteens.no_favorite_prefix' | translate }} diff --git a/src/app/modules/dashboard/sections/navigation-section/menu-item.interface.ts b/src/app/modules/dashboard/sections/navigation-section/menu-item.interface.ts deleted file mode 100644 index 81541367..00000000 --- a/src/app/modules/dashboard/sections/navigation-section/menu-item.interface.ts +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2022 StApps - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - */ - -export interface MenuItemInterface { - icon: string; - label: string; - link: string; -} - -export enum MenuItemKey { - CATALOG = 'catalog', - CANTEEN = 'canteen', - MAP = 'map', - SETTINGS = 'settings', - SEARCH = 'search', -} - -export type MenuItemConfig = Record; diff --git a/src/app/modules/dashboard/sections/navigation-section/menu-items.config.ts b/src/app/modules/dashboard/sections/navigation-section/menu-items.config.ts deleted file mode 100644 index ed598c61..00000000 --- a/src/app/modules/dashboard/sections/navigation-section/menu-items.config.ts +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2022 StApps - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - */ - -import {MenuItemInterface, MenuItemKey} from './menu-item.interface'; -import {SCIcon} from '../../../../util/ion-icon/icon'; - -export const MENU_ITEMS: Record = { - catalog: { - icon: SCIcon`book`, - label: 'dashboard.navigation.item.catalog', - link: '/catalog', - }, - canteen: { - icon: SCIcon`local_cafe`, - label: 'dashboard.navigation.item.canteen', - link: '/canteen', - }, - map: { - icon: SCIcon`map`, - label: 'dashboard.navigation.item.map', - link: '/map', - }, - settings: { - icon: SCIcon`settings`, - label: 'dashboard.navigation.item.settings', - link: '/settings', - }, - search: { - icon: SCIcon`search`, - label: 'dashboard.navigation.item.search', - link: '/search', - }, -}; - -export const DEFAULT_ACTIVE_MENU_ITEMS: MenuItemKey[] = [ - MenuItemKey.CATALOG, - MenuItemKey.CANTEEN, - MenuItemKey.MAP, - MenuItemKey.SETTINGS, - MenuItemKey.SEARCH, -]; diff --git a/src/app/modules/dashboard/sections/navigation-section/navigation-section.component.html b/src/app/modules/dashboard/sections/navigation-section/navigation-section.component.html deleted file mode 100644 index 717a59c1..00000000 --- a/src/app/modules/dashboard/sections/navigation-section/navigation-section.component.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - {{ menuItems[item].label | translate }} - - - - diff --git a/src/app/modules/dashboard/sections/navigation-section/navigation-section.component.scss b/src/app/modules/dashboard/sections/navigation-section/navigation-section.component.scss deleted file mode 100644 index e87cc4f3..00000000 --- a/src/app/modules/dashboard/sections/navigation-section/navigation-section.component.scss +++ /dev/null @@ -1,32 +0,0 @@ -/*! - * Copyright (C) 2022 StApps - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - */ - -.navigation-swiper.swiper { - .swiper-slide { - a { - font-family: var(--ion-font-family); - font-size: var(--font-size-xs); - font-weight: var(--font-weight-semi-bold); - text-align: center; - padding: var(--spacing-md) var(--spacing-lg); - justify-content: center; - } - - ion-icon { - display: block; - margin: auto; - } - } -} diff --git a/src/app/modules/dashboard/sections/navigation-section/navigation-section.component.ts b/src/app/modules/dashboard/sections/navigation-section/navigation-section.component.ts deleted file mode 100644 index a0c460a1..00000000 --- a/src/app/modules/dashboard/sections/navigation-section/navigation-section.component.ts +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2022 StApps - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - */ -import {Component, OnInit, ViewEncapsulation} from '@angular/core'; -import {ModalController} from '@ionic/angular'; -import {EditModalComponent} from '../../edit-modal/edit-modal.component'; -import {DEFAULT_ACTIVE_MENU_ITEMS, MENU_ITEMS} from './menu-items.config'; -import {MenuItemKey} from './menu-item.interface'; -import {EditModalItem, EditModalTypeEnum} from '../../edit-modal/edit-modal-type.enum'; -import {StorageProvider} from '../../../storage/storage.provider'; -import {TranslatePipe} from '@ngx-translate/core'; - -const DASHBOARD_NAVIGATION = 'stapps.dashboard.navigation'; - -/** - * Shows a horizontal list of navigation items - */ -@Component({ - selector: 'stapps-navigation-section', - templateUrl: 'navigation-section.component.html', - styleUrls: ['navigation-section.component.scss'], - encapsulation: ViewEncapsulation.None, -}) -export class NavigationSectionComponent implements OnInit { - /** - * Slider options - */ - sliderOptions = { - spaceBetween: 12, - freeMode: { - enabled: true, - sticky: true, - }, - width: 120, - }; - - menuItems = MENU_ITEMS; - - activeMenuItems: MenuItemKey[] = DEFAULT_ACTIVE_MENU_ITEMS; - - constructor( - public modalController: ModalController, - private storageProvider: StorageProvider, - private translatePipe: TranslatePipe, - ) {} - - ngOnInit() { - void this.getItems(); - } - - /** - * Get current order of items - */ - async getItems() { - if (await this.storageProvider.has(DASHBOARD_NAVIGATION)) { - const storedMenuItems: string = await this.storageProvider.get(DASHBOARD_NAVIGATION); - if (storedMenuItems) { - const parsedMenuItems = JSON.parse(storedMenuItems); - if (Array.isArray(parsedMenuItems) && parsedMenuItems.every(it => typeof it === 'string')) { - this.activeMenuItems = parsedMenuItems; - } - } - } - } - - /** - * Save updated order of items - */ - updateActiveItems(items: MenuItemKey[]) { - this.activeMenuItems = items; - void this.storageProvider.put(DASHBOARD_NAVIGATION, JSON.stringify(this.activeMenuItems)); - } - - /** - * Action when user clicked edit to this section - */ - async onSectionEdit() { - const modal = await this.modalController.create({ - component: EditModalComponent, - canDismiss: true, - componentProps: { - items: Object.entries(this.menuItems).map(([id, item]) => ({ - id, - active: this.activeMenuItems.includes(id as MenuItemKey), - labelLocalized: this.translatePipe.transform(item.label), - })), - type: EditModalTypeEnum.CHECKBOXES, - }, - }); - await modal.present(); - - modal.onDidDismiss().then(result => { - if (result.data?.items) { - this.updateActiveItems( - result.data.items.filter((it: EditModalItem) => it.active).map((it: EditModalItem) => it.id), - ); - } - }); - } -} diff --git a/src/app/modules/dashboard/sections/news-section/news-section.component.html b/src/app/modules/dashboard/sections/news-section/news-section.component.html index f6641fc9..4bcb7516 100644 --- a/src/app/modules/dashboard/sections/news-section/news-section.component.html +++ b/src/app/modules/dashboard/sections/news-section/news-section.component.html @@ -13,14 +13,11 @@ ~ this program. If not, see . --> - - + + + + + {{ 'dashboard.news.moreNews' | translate | titlecase }} diff --git a/src/app/modules/dashboard/sections/news-section/news-section.component.ts b/src/app/modules/dashboard/sections/news-section/news-section.component.ts index 23b55a20..98b5e223 100644 --- a/src/app/modules/dashboard/sections/news-section/news-section.component.ts +++ b/src/app/modules/dashboard/sections/news-section/news-section.component.ts @@ -12,15 +12,11 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {Component, OnInit} from '@angular/core'; -import {Router} from '@angular/router'; -import {NewsPageComponent} from '../../../news/page/news-page.component'; +import {Component} from '@angular/core'; import {NewsProvider} from '../../../news/news.provider'; -import {SettingsProvider} from '../../../settings/settings.provider'; -import {newsFilterSettingsFieldsMapping, NewsFilterSettingsNames} from '../../../news/news-filter-settings'; -import {DataProvider} from '../../../data/data.provider'; -import {SCSearchValueFilter} from '@openstapps/core'; +import {SCMessage} from '@openstapps/core'; import {animate, style, transition, trigger} from '@angular/animations'; +import {Router} from '@angular/router'; /** * Shows a section with news @@ -38,40 +34,12 @@ import {animate, style, transition, trigger} from '@angular/animations'; ]), ], }) -export class NewsSectionComponent extends NewsPageComponent implements OnInit { - pageSize = 5; +export class NewsSectionComponent { + news: Promise; - /** - * A map of the filters where the keys are settings names - */ - filtersMap = new Map(); - - constructor(newsProvider: NewsProvider, settingsProvider: SettingsProvider, private router: Router) { - super(newsProvider, settingsProvider); - } - - async ngOnInit() { - await super.ngOnInit(); - for (const setting of this.settings) { - this.filtersMap.set( - setting.name as NewsFilterSettingsNames, - DataProvider.createValueFilter( - newsFilterSettingsFieldsMapping[setting.name as NewsFilterSettingsNames], - setting.value as string, - ), - ); - } - - this.filters = [...this.filtersMap.values()]; - - try { - await this.fetchNews(); - } catch { - this.news = []; - } - } - - onMoreNewsClicked() { - void this.router.navigate(['/news']); + constructor(readonly newsProvider: NewsProvider, readonly router: Router) { + this.news = this.newsProvider + .getCurrentFilters() + .then(filters => this.newsProvider.getList(5, 0, filters)); } } diff --git a/src/app/modules/dashboard/sections/search-section/search-route-transition.ts b/src/app/modules/dashboard/sections/search-section/search-route-transition.ts new file mode 100644 index 00000000..9ea8d976 --- /dev/null +++ b/src/app/modules/dashboard/sections/search-section/search-route-transition.ts @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2023 StApps + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +import {AnimationController} from '@ionic/angular'; +import {AnimationOptions} from '@ionic/angular/providers/nav-controller'; + +/** + * + */ +export function homePageSearchTransition(animationController: AnimationController) { + let scheduleTransform: WebKitCSSMatrix; + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + return (_baseElement: HTMLElement, options: AnimationOptions | any) => { + const back = options.direction === 'back'; + const searchPage = back ? options.leavingEl : options.enteringEl; + const homePage = back ? options.enteringEl : options.leavingEl; + const rootTransition = animationController + .create() + .duration(options.duration ?? 350) + .easing( + // quintic in / out + back ? 'cubic-bezier(0.64, 0, 0.78, 0)' : 'cubic-bezier(0.22, 1, 0.36, 1)', + ); + + const homePageContent = homePage.querySelector('ion-content').shadowRoot.querySelector('.inner-scroll'); + const leavingSearchbar = homePage.querySelector('ion-searchbar'); + const enteringSearchbar = searchPage.querySelector('ion-searchbar'); + const searchPageHeader = searchPage.querySelector('ion-header'); + const homePageSchedule = homePage.querySelector('.schedule'); + + if (!back) { + scheduleTransform = new WebKitCSSMatrix(window.getComputedStyle(homePageSchedule).transform); + } + const enteringSearchbarTop = enteringSearchbar.getBoundingClientRect().top; + const leavingSearchbarTop = leavingSearchbar.getBoundingClientRect().top; + const searchbarDelta = leavingSearchbarTop - enteringSearchbarTop; + const searchHeaderHeight = searchPageHeader.getBoundingClientRect().bottom; + const homeHeaderHeight = homePageSchedule.getBoundingClientRect().bottom; + const homePageSlideAmount = -50; + const headerDelta = homeHeaderHeight - searchHeaderHeight; + + const enterTransition = animationController.create().fromTo('opacity', '0', '1').addElement(searchPage); + const exitTransition = animationController.create().fromTo('opacity', '1', '1').addElement(homePage); + + const homePageSlide = animationController + .create() + .fromTo('transform', `translateY(0px)`, `translateY(${homePageSlideAmount}px)`) + .addElement(homePageContent); + + const toolbarExit = animationController + .create() + .fromTo( + 'transform', + scheduleTransform.toString(), + scheduleTransform.translate(undefined, -headerDelta).toString(), + ) + .addElement(homePageSchedule); + const headerSlide = animationController + .create() + .fromTo('transform', `translateY(${headerDelta}px)`, 'translateY(0px)') + .addElement(searchPageHeader); + + const searchbarSlideIn = animationController + .create() + .fromTo('transform', `translateY(${searchbarDelta - headerDelta}px)`, 'translateY(0px)') + .beforeStyles({ + 'z-index': 1000, + }) + .afterClearStyles(['z-index']) + .addElement(searchPage.querySelector('.toolbar-searchbar')); + const searchbarSlideOut = animationController + .create() + .fromTo('transform', 'translateY(0px)', `translateY(-${searchbarDelta + homePageSlideAmount}px)`) + .addElement(homePage.querySelector('stapps-search-section > stapps-section')); + + rootTransition + .addAnimation([ + enterTransition, + exitTransition, + toolbarExit, + homePageSlide, + headerSlide, + searchbarSlideIn, + searchbarSlideOut, + ]) + .direction(back ? 'reverse' : 'normal'); + return rootTransition; + }; +} diff --git a/src/app/modules/dashboard/sections/search-section/search-section.component.html b/src/app/modules/dashboard/sections/search-section/search-section.component.html index 973ac86a..6365aa5f 100644 --- a/src/app/modules/dashboard/sections/search-section/search-section.component.html +++ b/src/app/modules/dashboard/sections/search-section/search-section.component.html @@ -1,5 +1,5 @@ - - + + + + diff --git a/src/app/modules/dashboard/sections/search-section/search-section.component.scss b/src/app/modules/dashboard/sections/search-section/search-section.component.scss index 12b18470..4af0e644 100644 --- a/src/app/modules/dashboard/sections/search-section/search-section.component.scss +++ b/src/app/modules/dashboard/sections/search-section/search-section.component.scss @@ -1,36 +1,43 @@ /*! - * Copyright (C) 2022 StApps - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 3. + * Copyright (C) 2023 StApps + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, version 3. * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . */ -.searchbar { - position: relative; - max-width: 700px; +ion-ripple-effect { + z-index: 1000; + border-radius: var(--spacing-sm); +} - ion-input { - background: var(--ion-color-field-bg); - border-radius: var(--border-radius-default); - --padding-start: var(--spacing-md); - --padding-end: var(--spacing-md); - --padding-top: var(--spacing-md); - --padding-bottom: var(--spacing-md); - box-shadow: var(--shadow-default); +ion-searchbar { + cursor: text; +} + +ion-searchbar ::ng-deep .searchbar-input-container { + pointer-events: none; +} + +ion-searchbar.ios { + ion-ripple-effect { + display: none; } - ion-icon { - position: absolute; - top: 50%; - right: var(--spacing-md); - transform: translateY(-50%); - z-index: 2; + + transition: opacity 150ms ease; + &:active { + opacity: 0.6; + } + @media (hover: hover) { + &:hover { + opacity: 0.6; + } } } diff --git a/src/app/modules/dashboard/sections/search-section/search-section.component.ts b/src/app/modules/dashboard/sections/search-section/search-section.component.ts index 3c0d111d..053241f7 100644 --- a/src/app/modules/dashboard/sections/search-section/search-section.component.ts +++ b/src/app/modules/dashboard/sections/search-section/search-section.component.ts @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 StApps + * Copyright (C) 2023 StApps * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation, version 3. @@ -16,6 +16,8 @@ import {Component} from '@angular/core'; import {Router} from '@angular/router'; import {Capacitor} from '@capacitor/core'; import {Keyboard} from '@capacitor/keyboard'; +import {AnimationBuilder, AnimationController} from '@ionic/angular'; +import {homePageSearchTransition} from './search-route-transition'; /** * Shows a search input field @@ -28,7 +30,11 @@ import {Keyboard} from '@capacitor/keyboard'; export class SearchSectionComponent { searchTerm = ''; - constructor(private router: Router) {} + routeTransition: AnimationBuilder; + + constructor(private router: Router, private animationController: AnimationController) { + this.routeTransition = homePageSearchTransition(this.animationController); + } /** * User submits search diff --git a/src/app/modules/data/list/search-page.html b/src/app/modules/data/list/search-page.html index 6e2b4df5..1ae5bc0d 100644 --- a/src/app/modules/data/list/search-page.html +++ b/src/app/modules/data/list/search-page.html @@ -1,5 +1,5 @@ - - - {{ 'name' | translateSimple: item }} - - - - - - - {{ 'profile.buttons.default.log_' + (isLoggedIn ? 'out' : 'in') | translate }} - - - - - - + + + + + + {{ 'profile.buttons.default.log_' + (isLoggedIn ? 'out' : 'in') | translate }} + + + + - - + > +
+ + {{ 'name' | translateSimple: link }} +
+
+
+
diff --git a/src/app/modules/profile/page/profile-page-section.scss b/src/app/modules/profile/page/profile-page-section.scss index 1696b9c4..fd2d18f1 100644 --- a/src/app/modules/profile/page/profile-page-section.scss +++ b/src/app/modules/profile/page/profile-page-section.scss @@ -12,9 +12,50 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ +$width: 108px; -.section-headline { - padding-inline-start: var(--spacing-md); +simple-swiper { + container-type: inline-size; + --swiper-slide-width: #{$width}; + + ion-item { + @each $i in 7, 6, 5, 4, 3, 2, 1 { + $max: #{($width + 8px) * $i}; + @container (inline-size < #{$max}) { + --swiper-slide-width: #{100cqi / $i}; + } + } + } +} + +ion-item { + height: 96px; + --border-radius: var(--border-radius-default); + --inner-padding-start: unset; + --inner-padding-end: unset; + --padding-start: unset; + --padding-end: unset; + + > div { + width: 100%; + height: 100%; + } + + div, + ion-label { + white-space: normal; + text-align: center; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + font-size: var(--font-size-sm); + } + + &::part(native) { + height: 100%; + width: 100%; + } } .log-in-hint { @@ -23,47 +64,3 @@ box-shadow: none; background: var(--ion-color-light-tint); } - -.navigation::part(native) { - padding-inline: 0; -} - -swiper { - //noinspection CssInvalidFunction - transform: translateY(calc(-1 * var(--spacing-sm))); -} - -stapps-section-link-card { - // required spacing for box shadow - margin-block: var(--spacing-sm); -} - -:host { - display: grid; - grid-template-columns: 1fr auto auto auto; - grid-template-rows: 42px 1fr; - grid-template-areas: - 'title prev next login' - 'swiper swiper swiper swiper'; - align-items: center; - - > ion-label { - margin-block-end: 0; - } - - > swiper { - grid-area: swiper; - width: 100%; - padding-right: 0; - } -} - -ion-button.hidden { - display: none; -} - -@media (hover: none) { - ion-button.navigation { - display: none; - } -} diff --git a/src/app/modules/profile/profile.module.ts b/src/app/modules/profile/profile.module.ts index f005f338..fc09fc83 100644 --- a/src/app/modules/profile/profile.module.ts +++ b/src/app/modules/profile/profile.module.ts @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 StApps + * Copyright (C) 2023 StApps * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation, version 3. @@ -25,7 +25,6 @@ import {UtilModule} from '../../util/util.module'; import {IonIconModule} from '../../util/ion-icon/ion-icon.module'; import {ProfilePageSectionComponent} from './page/profile-page-section.component'; import {ThingTranslateModule} from '../../translation/thing-translate.module'; -import {SectionModule} from '../../util/section/section.module'; const routes: Routes = [ { @@ -46,7 +45,6 @@ const routes: Routes = [ SwiperModule, UtilModule, ThingTranslateModule, - SectionModule, ], }) export class ProfilePageModule {} diff --git a/src/app/util/searchbar-autofocus.directive.ts b/src/app/util/searchbar-autofocus.directive.ts new file mode 100644 index 00000000..f896948f --- /dev/null +++ b/src/app/util/searchbar-autofocus.directive.ts @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2023 StApps + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +import {AfterViewInit, Directive, ElementRef} from '@angular/core'; +import {IonSearchbar} from '@ionic/angular'; + +@Directive({ + selector: 'ion-searchbar[autofocus]', +}) +export class SearchbarAutofocusDirective implements AfterViewInit { + constructor(private element: ElementRef) {} + + ngAfterViewInit() { + const label = `focus`; + console.time(label); + const interval = setInterval(() => { + const searchbar = this.element.nativeElement as IonSearchbar; + searchbar.setFocus(); + }); + const onFocus = () => { + console.timeEnd(label); + clearInterval(interval); + this.element.nativeElement.removeEventListener('ionFocus', onFocus); + }; + this.element.nativeElement.addEventListener('ionFocus', onFocus); + } +} diff --git a/src/app/modules/dashboard/section/section.component.html b/src/app/util/section.component.html similarity index 78% rename from src/app/modules/dashboard/section/section.component.html rename to src/app/util/section.component.html index b86a305d..469f032b 100644 --- a/src/app/modules/dashboard/section/section.component.html +++ b/src/app/util/section.component.html @@ -37,20 +37,14 @@
- - - - - - - - - - + +
+ +
- + diff --git a/src/app/modules/dashboard/section/section.component.scss b/src/app/util/section.component.scss similarity index 92% rename from src/app/modules/dashboard/section/section.component.scss rename to src/app/util/section.component.scss index 493b2b4d..7d31943e 100644 --- a/src/app/modules/dashboard/section/section.component.scss +++ b/src/app/util/section.component.scss @@ -13,7 +13,7 @@ * this program. If not, see . */ -@import '../../../../theme/util/mixins'; +@import 'src/theme/util/mixins'; a { display: contents; @@ -44,8 +44,8 @@ ion-col { padding: 0; } -ion-button::part(native) { - padding-inline: var(--spacing-sm); +:host ::ng-deep ion-button::part(native) { + padding-inline: var(--spacing-xs); } @media (hover: none) { diff --git a/src/app/modules/dashboard/section/section.component.ts b/src/app/util/section.component.ts similarity index 69% rename from src/app/modules/dashboard/section/section.component.ts rename to src/app/util/section.component.ts index da4ab703..b0504acc 100644 --- a/src/app/modules/dashboard/section/section.component.ts +++ b/src/app/util/section.component.ts @@ -12,17 +12,7 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import { - AfterContentInit, - Component, - EventEmitter, - HostBinding, - Input, - OnDestroy, - OnInit, - Output, - ViewContainerRef, -} from '@angular/core'; +import {AfterContentInit, Component, Input, OnDestroy, ViewContainerRef} from '@angular/core'; import {SCThings} from '@openstapps/core'; /** @@ -33,35 +23,17 @@ import {SCThings} from '@openstapps/core'; templateUrl: 'section.component.html', styleUrls: ['section.component.scss'], }) -export class SectionComponent implements OnInit, AfterContentInit, OnDestroy { - @HostBinding('class.is-extended') isExtendedClass = false; - - @HostBinding('class.is-editable') isEditableClass = false; - +export class SectionComponent implements AfterContentInit, OnDestroy { @Input() title = ''; - @Input() isSectionExtended = false; - - @Input() isEditable = false; - - @Input() customIcon?: string = undefined; - @Input() item?: SCThings; - // eslint-disable-next-line @angular-eslint/no-output-on-prefix - @Output() onEdit = new EventEmitter(); - mutationObserver: MutationObserver; swiper?: HTMLElement; constructor(readonly viewContainerRef: ViewContainerRef) {} - ngOnInit() { - this.isExtendedClass = this.isSectionExtended; - this.isEditableClass = this.isEditable; - } - ngAfterContentInit() { this.mutationObserver = new MutationObserver(() => { const simpleSwiper = this.viewContainerRef.element.nativeElement.querySelector('simple-swiper'); @@ -93,13 +65,6 @@ export class SectionComponent implements OnInit, AfterContentInit, OnDestroy { } } - /** - * Action when edit is clicked - */ - onEditClick() { - this.onEdit.emit(); - } - ngOnDestroy() { this.mutationObserver.disconnect(); } diff --git a/src/app/util/section/section-link-card.component.ts b/src/app/util/section/section-link-card.component.ts deleted file mode 100644 index 8ababa0e..00000000 --- a/src/app/util/section/section-link-card.component.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2022 StApps - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - */ -import {Component, Input} from '@angular/core'; -import {SCSectionLink} from '../../modules/profile/page/sections'; - -@Component({ - selector: 'stapps-section-link-card', - templateUrl: 'section-link-card.html', - styleUrls: ['section-link-card.scss'], -}) -export class SectionLinkCardComponent { - @Input() item: SCSectionLink; - - @Input() disabled: boolean; -} diff --git a/src/app/util/section/section-link-card.html b/src/app/util/section/section-link-card.html deleted file mode 100644 index e1ba8732..00000000 --- a/src/app/util/section/section-link-card.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - {{ 'name' | translateSimple: item }} - - - diff --git a/src/app/util/section/section-link-card.scss b/src/app/util/section/section-link-card.scss deleted file mode 100644 index 72c0cd4e..00000000 --- a/src/app/util/section/section-link-card.scss +++ /dev/null @@ -1,49 +0,0 @@ -/*! - * Copyright (C) 2023 StApps - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - */ - -:host, -ion-card, -ion-card-header, -ion-card::part(native) { - height: 100%; -} - -ion-card { - padding: 0; - margin-block: 0; - margin-inline: var(--spacing-sm); -} - -ion-card-header { - padding: var(--spacing-md) var(--spacing-lg); -} - -ion-card-title { - padding: 0; - - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - text-align: center; - - font-family: var(--ion-font-family); - font-size: var(--font-size-xs); - font-weight: var(--font-weight-semi-bold); -} - -.disabled { - opacity: 0.3; -} diff --git a/src/app/util/section/section-tail-prompt-card.component.ts b/src/app/util/section/section-tail-prompt-card.component.ts deleted file mode 100644 index 7724a3eb..00000000 --- a/src/app/util/section/section-tail-prompt-card.component.ts +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2022 StApps - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - */ - -import {Component} from '@angular/core'; - -@Component({ - selector: 'stapps-section-tail-prompt-card', - templateUrl: 'section-tail-prompt-card.html', - styleUrls: ['section-tail-prompt-card.scss', 'section-link-card.scss'], -}) -export class SectionTailPromptCardComponent {} diff --git a/src/app/util/section/section-tail-prompt-card.html b/src/app/util/section/section-tail-prompt-card.html deleted file mode 100644 index 934fd67f..00000000 --- a/src/app/util/section/section-tail-prompt-card.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - diff --git a/src/app/util/section/section-tail-prompt-card.scss b/src/app/util/section/section-tail-prompt-card.scss deleted file mode 100644 index e8a1d018..00000000 --- a/src/app/util/section/section-tail-prompt-card.scss +++ /dev/null @@ -1,19 +0,0 @@ -/*! - * Copyright (C) 2022 StApps - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - */ - -.card { - box-shadow: none; - background: none; -} diff --git a/src/app/util/section/section.module.ts b/src/app/util/section/section.module.ts deleted file mode 100644 index 1ececf42..00000000 --- a/src/app/util/section/section.module.ts +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (C) 2023 StApps - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - */ -import {NgModule} from '@angular/core'; -import {SectionLinkCardComponent} from './section-link-card.component'; -import {IonicModule} from '@ionic/angular'; -import {BrowserModule} from '@angular/platform-browser'; -import {TranslateModule} from '@ngx-translate/core'; -import {IonIconModule} from '../ion-icon/ion-icon.module'; -import {ThingTranslateModule} from '../../translation/thing-translate.module'; -import {RouterModule} from '@angular/router'; -import {SectionTailPromptCardComponent} from './section-tail-prompt-card.component'; - -@NgModule({ - imports: [BrowserModule, IonicModule, TranslateModule, IonIconModule, ThingTranslateModule, RouterModule], - declarations: [SectionLinkCardComponent, SectionTailPromptCardComponent], - exports: [SectionLinkCardComponent, SectionTailPromptCardComponent], -}) -export class SectionModule {} diff --git a/src/app/util/util.module.ts b/src/app/util/util.module.ts index cc64ee50..c003e269 100644 --- a/src/app/util/util.module.ts +++ b/src/app/util/util.module.ts @@ -28,6 +28,8 @@ import {ElementSizeChangeDirective} from './element-size-change.directive'; import {OpeningHoursComponent} from './opening-hours.component'; import {ThingTranslateModule} from '../translation/thing-translate.module'; import {SimpleSwiperComponent} from './simple-swiper.component'; +import {SearchbarAutofocusDirective} from './searchbar-autofocus.directive'; +import {SectionComponent} from './section.component'; @NgModule({ imports: [BrowserModule, IonicModule, TranslateModule, ThingTranslateModule.forChild()], @@ -37,12 +39,14 @@ import {SimpleSwiperComponent} from './simple-swiper.component'; DateIsThisPipe, NullishCoalescingPipe, LazyPipe, + SectionComponent, DateFromIndexPipe, DaytimeKeyPipe, NextDateInListPipe, EditModalComponent, OpeningHoursComponent, SimpleSwiperComponent, + SearchbarAutofocusDirective, ], exports: [ ElementSizeChangeDirective, @@ -52,10 +56,12 @@ import {SimpleSwiperComponent} from './simple-swiper.component'; LazyPipe, DateFromIndexPipe, DaytimeKeyPipe, + SectionComponent, NextDateInListPipe, EditModalComponent, OpeningHoursComponent, SimpleSwiperComponent, + SearchbarAutofocusDirective, ], }) export class UtilModule {} diff --git a/src/theme/common/_ion-toolbar.scss b/src/theme/common/_ion-toolbar.scss index 0b81b377..ade500e4 100644 --- a/src/theme/common/_ion-toolbar.scss +++ b/src/theme/common/_ion-toolbar.scss @@ -1,5 +1,5 @@ /*! - * Copyright (C) 2022 StApps + * Copyright (C) 2023 StApps * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation, version 3. @@ -37,12 +37,6 @@ app-root ion-toolbar.in-toolbar { --padding-bottom: 0; } - ion-searchbar { - padding-left: 0; - padding-right: 0; - --box-shadow: none; - } - ion-segment { &:last-of-type { --padding-bottom: 0; @@ -74,3 +68,10 @@ app-root ion-toolbar.in-toolbar { height: 42px; // this prevents the back button to become a .x px value } } + +app-root ion-toolbar.in-toolbar ion-searchbar, +.stapps-searchbar { + padding-left: 0; + padding-right: 0; + --box-shadow: none; +} diff --git a/tsconfig.app.json b/tsconfig.app.json index 23a144c2..65c9a8a4 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -3,10 +3,6 @@ "compilerOptions": { "outDir": "../out-tsc/app" }, - "files": [ - "src/main.ts", - "src/polyfills.ts", - "src/app/modules/dashboard/sections/navigation-section/menu-item.interface.ts" - ], + "files": ["src/main.ts", "src/polyfills.ts"], "include": ["src/**/*.d.ts"] }