From 33a74d96ae92137f53a775e90bff99e5f2d41f6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thea=20Sch=C3=B6bl?= Date: Mon, 27 Feb 2023 14:44:20 +0000 Subject: [PATCH] feat: revamp dashboard mensa section --- cypress/integration/dashboard.spec.ts | 42 +++++--- .../dashboard/dashboard.component.scss | 75 +-------------- src/app/modules/dashboard/dashboard.module.ts | 4 +- .../dashboard/section/section.component.html | 56 ++++++++--- .../dashboard/section/section.component.scss | 95 ++++++++++--------- .../dashboard/section/section.component.ts | 60 +++++++++++- .../favorites-section.component.html | 31 +++--- .../favorites-section.component.scss | 44 ++------- .../mensa-section-content.component.html | 51 ++++++---- .../mensa-section-content.component.scss | 28 ++++++ .../mensa-section-content.component.ts | 61 ++++-------- .../mensa-section.component.html | 49 ++++++---- .../mensa-section.component.scss | 28 ++++++ .../mensa-section/mensa-section.component.ts | 4 + .../news-section/news-section.component.html | 33 ++----- .../news-section/news-section.component.scss | 67 +++++-------- .../news-section/news-section.component.ts | 31 +++--- .../modules/data/elements/offers-in-list.html | 22 ++--- .../data/list/data-list-item.component.ts | 10 +- src/app/modules/data/list/data-list-item.html | 6 +- src/app/modules/data/list/data-list-item.scss | 40 ++++++++ src/app/modules/news/item/news-item.scss | 6 +- src/app/modules/news/news.module.ts | 21 ++-- src/app/util/simple-swiper.component.ts | 27 ++++++ src/app/util/simple-swiper.html | 15 +++ src/app/util/simple-swiper.scss | 54 +++++++++++ src/app/util/util.module.ts | 3 + 27 files changed, 578 insertions(+), 385 deletions(-) create mode 100644 src/app/modules/dashboard/sections/mensa-section/mensa-section-content.component.scss create mode 100644 src/app/util/simple-swiper.component.ts create mode 100644 src/app/util/simple-swiper.html create mode 100644 src/app/util/simple-swiper.scss diff --git a/cypress/integration/dashboard.spec.ts b/cypress/integration/dashboard.spec.ts index e973ef2a..97a3b579 100644 --- a/cypress/integration/dashboard.spec.ts +++ b/cypress/integration/dashboard.spec.ts @@ -58,14 +58,15 @@ describe('dashboard', async function () { cy.visit('/overview'); cy.get('stapps-mensa-section').within(() => { - cy.get('.card').should('have.length', 1); - cy.get('.card > ion-label > a').should('have.text', 'Übersicht der Mensen'); + cy.get('swiper').should('not.exist'); + cy.get('.nothing-selected > ion-label > a').should('have.text', 'Übersicht der Mensen'); }); }); it('should add a mensa', function () { + cy.clock(new Date('2022-06-08'), ['Date']); cy.visit('/overview'); - cy.get('stapps-mensa-section').find('.card > ion-label > a').click(); + cy.get('stapps-mensa-section').find('.nothing-selected > ion-label > a').click(); cy.intercept('POST', 'https://mobile.server.uni-frankfurt.de/search', { fixture: 'search/types/canteen/canteen-search-result.json', }); @@ -74,7 +75,7 @@ describe('dashboard', async function () { fixture: 'search/types/dish/dish-2.json', }); cy.get('ion-back-button').click(); - cy.get('stapps-mensa-section').find('.card').should('have.length.greaterThan', 1); + cy.get('stapps-mensa-section').find('simple-swiper > *').should('have.length.greaterThan', 1); }); }); @@ -85,24 +86,35 @@ describe('dashboard', async function () { }).as('search'); }); - it('should have desktop navigation buttons', function () { - cy.visit('/overview'); + // TODO: Cypress has no real way of setting the presence of a pointing device, + // which means the behavior is undefined and depends on the testing device + // it('should have desktop navigation buttons', function () { + // cy.visit('/overview'); + // + // cy.get('stapps-news-section').within(function () { + // cy.get('.swiper-button').should('not.have.css', 'display: none'); + // }); + // }); - cy.get('stapps-news-section').within(function () { - cy.get('.swiper-button-prev').should('exist'); - cy.get('.swiper-button-next').should('exist'); - }); - }); + // it('should not have desktop navigation buttons on mobile', function () { + // cy.visit('/overview'); + // + // cy.get('stapps-news-section').within(function () { + // cy.get('.swiper-button').should('have.css', 'display: none'); + // }); + // }); it('should have working desktop navigation', function () { cy.visit('/overview'); cy.get('stapps-news-section').within(function () { - cy.get('.swiper-slide-active').should('have.text', 'DE for Students and Employees'); + cy.get('simple-swiper > *').eq(0).should('be.visible'); - cy.get('.swiper-button-next').click({scrollBehavior: false}); + // TODO: see tests above, button will be visible or invisible + // depending on the testing device + cy.get('.swiper-button > ion-button').eq(1).click({scrollBehavior: false, force: true}); - cy.get('.swiper-slide-active').should('have.text', 'DE for Students'); + cy.get('simple-swiper > *').eq(0).should('not.be.visible'); }); }); @@ -113,7 +125,7 @@ describe('dashboard', async function () { fixture: 'search/types/message/single-message.json', }).as('search'); - cy.get('stapps-news-section').contains('a', 'Mehr Nachrichten').click(); + cy.get('stapps-news-section').contains('ion-item', 'Mehr Nachrichten').click(); cy.url().should('include', '/news'); }); }); diff --git a/src/app/modules/dashboard/dashboard.component.scss b/src/app/modules/dashboard/dashboard.component.scss index e1da6e75..76cee475 100644 --- a/src/app/modules/dashboard/dashboard.component.scss +++ b/src/app/modules/dashboard/dashboard.component.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. @@ -49,6 +49,7 @@ ion-content { --background: var(--ion-color-light); + --padding-bottom: var(--spacing-xl); } .schedule { @@ -140,75 +141,3 @@ ion-content { } } } - -.section { - padding: var(--spacing-md); - - &.section-extended { - padding-right: 0; - - ion-icon[name='edit'] { - margin-right: var(--spacing-md); - } - } - - &:first-of-type { - padding-top: var(--spacing-lg); - } - - & > ion-label:first-child { - font-family: var(--headline-font-family); - font-size: var(--font-size-lg); - font-weight: var(--font-weight-semi-bold); - text-transform: uppercase; - margin-bottom: var(--spacing-md); - - width: 100%; - display: flex; - flex-direction: revert; - justify-content: space-between; - - ion-icon { - color: var(--ion-color-medium-shade); - width: 25px; - height: 25px; - } - } -} - -.swiper { - background-color: var(--ion-color-primary-contrast); - border-radius: var(--border-radius-default); - padding: var(--spacing-lg); - width: 28%; - - display: flex; - flex-direction: column; - font-size: var(--font-size-xs); - font-weight: var(--font-weight-bold); - - ion-icon { - width: 40px; - height: 40px; - margin-bottom: var(--spacing-xs); - } -} - -ion-searchbar { - padding: 0; - --background: var(--ion-color-primary-contrast); - - ::ng-deep .searchbar-input-container { - height: 100%; - - input { - padding: var(--spacing-lg); - } - - ion-icon { - left: auto; - right: var(--spacing-lg); - width: 30px; - } - } -} diff --git a/src/app/modules/dashboard/dashboard.module.ts b/src/app/modules/dashboard/dashboard.module.ts index 14a9ab38..b1b10e79 100644 --- a/src/app/modules/dashboard/dashboard.module.ts +++ b/src/app/modules/dashboard/dashboard.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. @@ -34,6 +34,7 @@ import {FavoritesSectionComponent} from './sections/favorites-section/favorites- import {ThingTranslateModule} from '../../translation/thing-translate.module'; import {UtilModule} from '../../util/util.module'; import {IonIconModule} from '../../util/ion-icon/ion-icon.module'; +import {NewsModule} from '../news/news.module'; const catalogRoutes: Routes = [ { @@ -69,6 +70,7 @@ const catalogRoutes: Routes = [ SwiperModule, ThingTranslateModule.forChild(), UtilModule, + NewsModule, ], providers: [SettingsProvider, TranslatePipe], exports: [EditModalComponent], diff --git a/src/app/modules/dashboard/section/section.component.html b/src/app/modules/dashboard/section/section.component.html index ea32cd3b..b86a305d 100644 --- a/src/app/modules/dashboard/section/section.component.html +++ b/src/app/modules/dashboard/section/section.component.html @@ -1,5 +1,5 @@ + + + + + + -{{ title }} - - - - + + {{ title }} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/app/modules/dashboard/section/section.component.scss b/src/app/modules/dashboard/section/section.component.scss index 5ae00030..493b2b4d 100644 --- a/src/app/modules/dashboard/section/section.component.scss +++ b/src/app/modules/dashboard/section/section.component.scss @@ -1,58 +1,67 @@ /*! - * 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 . */ @import '../../../../theme/util/mixins'; +a { + display: contents; + color: unset; + text-decoration: unset; +} + +ion-grid { + width: 100%; +} + +ion-label { + font-family: var(--headline-font-family); + font-weight: var(--font-weight-bold); + + &:only-child { + height: 100%; + display: flex; + align-items: center; + } +} + +ion-grid { + padding: 0; +} + +ion-col { + padding: 0; +} + +ion-button::part(native) { + padding-inline: var(--spacing-sm); +} + +@media (hover: none) { + .swiper-button { + display: none; + } +} + :host { display: block; padding: var(--spacing-sm) var(--spacing-md) var(--spacing-sm); + --swiper-scroll-padding: var(--spacing-md); + --swiper-gap: var(--spacing-sm); @include ion-md-up { padding: var(--spacing-lg) var(--spacing-xxl) var(--spacing-sm); - } - - &.is-editable ::ng-deep { - .swiper-button-prev { - right: 65px; - } - - .swiper-button-next { - right: 35px; - } - } - - &.is-extended { - padding-right: 0; - .icon-margin-right { - margin-right: var(--spacing-md); - } - } - - & > ion-label:first-child { - font-family: var(--headline-font-family); - font-weight: var(--font-weight-bold); - - ion-icon { - color: var(--ion-color-medium-shade); - position: relative; - margin-block: auto; - cursor: pointer; - - &:hover ::ng-deep stapps-icon { - --fill: 1; - } - } + --swiper-scroll-padding: var(--spacing-xxl); } } diff --git a/src/app/modules/dashboard/section/section.component.ts b/src/app/modules/dashboard/section/section.component.ts index fea556b5..da4ab703 100644 --- a/src/app/modules/dashboard/section/section.component.ts +++ b/src/app/modules/dashboard/section/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. @@ -12,7 +12,18 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {Component, EventEmitter, HostBinding, Input, OnInit, Output} from '@angular/core'; +import { + AfterContentInit, + Component, + EventEmitter, + HostBinding, + Input, + OnDestroy, + OnInit, + Output, + ViewContainerRef, +} from '@angular/core'; +import {SCThings} from '@openstapps/core'; /** * Shows a horizontal list of action chips @@ -22,7 +33,7 @@ import {Component, EventEmitter, HostBinding, Input, OnInit, Output} from '@angu templateUrl: 'section.component.html', styleUrls: ['section.component.scss'], }) -export class SectionComponent implements OnInit { +export class SectionComponent implements OnInit, AfterContentInit, OnDestroy { @HostBinding('class.is-extended') isExtendedClass = false; @HostBinding('class.is-editable') isEditableClass = false; @@ -35,18 +46,61 @@ export class SectionComponent implements OnInit { @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'); + if (!simpleSwiper) return; + + this.swiper = simpleSwiper; + }); + this.mutationObserver.observe(this.viewContainerRef.element.nativeElement, { + childList: true, + subtree: true, + }); + } + + slideNext() { + if (this.swiper) { + this.swiper.scrollBy({ + left: this.swiper.offsetWidth, + behavior: 'smooth', + }); + } + } + + slidePrev() { + if (this.swiper) { + this.swiper.scrollBy({ + left: -this.swiper.offsetWidth, + behavior: 'smooth', + }); + } + } + /** * Action when edit is clicked */ onEditClick() { this.onEdit.emit(); } + + ngOnDestroy() { + this.mutationObserver.disconnect(); + } } 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 27e8fe78..bcae0574 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 @@ -1,5 +1,5 @@ + + + + + + + + {{ 'dashboard.canteens.no_dishes_available' | translate }} + + + + +
+
diff --git a/src/app/modules/dashboard/sections/mensa-section/mensa-section-content.component.scss b/src/app/modules/dashboard/sections/mensa-section/mensa-section-content.component.scss new file mode 100644 index 00000000..df17c82c --- /dev/null +++ b/src/app/modules/dashboard/sections/mensa-section/mensa-section-content.component.scss @@ -0,0 +1,28 @@ +/*! + * 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 . + */ + +.no-dishes::part(native) { + background: none; + color: var(--ion-color-medium-shade); +} + +simple-swiper { + --swiper-slide-width: 180px; +} + +.placeholder, +stapps-data-list-item { + height: 140px; +} diff --git a/src/app/modules/dashboard/sections/mensa-section/mensa-section-content.component.ts b/src/app/modules/dashboard/sections/mensa-section/mensa-section-content.component.ts index f38d6028..4765f9a4 100644 --- a/src/app/modules/dashboard/sections/mensa-section/mensa-section-content.component.ts +++ b/src/app/modules/dashboard/sections/mensa-section/mensa-section-content.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. @@ -12,9 +12,11 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {Component, Input, OnInit, OnChanges, SimpleChanges} from '@angular/core'; +import {Component, Input} from '@angular/core'; import {SCDish, SCPlace, SCThings} from '@openstapps/core'; import {PlaceMensaService} from '../../../data/types/place/special/mensa/place-mensa-service'; +import {animate, style, transition, trigger} from '@angular/animations'; +import moment from 'moment'; /** * Shows a section with meals of the chosen mensa @@ -22,50 +24,29 @@ import {PlaceMensaService} from '../../../data/types/place/special/mensa/place-m @Component({ selector: 'stapps-mensa-section-content', templateUrl: 'mensa-section-content.component.html', - styleUrls: ['mensa-section.component.scss'], + styleUrls: ['mensa-section-content.component.scss'], + animations: [ + trigger('fade', [ + transition(':enter', [style({opacity: '0'}), animate('500ms ease', style({opacity: '1'}))]), + ]), + ], }) -export class MensaSectionContentComponent implements OnInit, OnChanges { - /** - * Slider options - */ - sliderOptions = { - spaceBetween: 12, - freeMode: { - enabled: true, - sticky: true, - }, - width: 120, - }; - +export class MensaSectionContentComponent { /** * Map of dishes for each day */ // eslint-disable-next-line unicorn/no-null - dishes: SCDish[] | null = []; + dishes: Promise; - @Input() items: SCThings[]; + @Input() set item(value: SCThings) { + if (!value) return; + this.dishes = this.mensaService.getAllDishes(value as SCPlace, 1).then(it => { + const closestDayWithDishes = Object.keys(it) + .filter(key => it[key].length > 0) + .find(key => moment(key).isSame(moment(), 'day')); + return closestDayWithDishes ? it[closestDayWithDishes] : []; + }); + } constructor(private readonly mensaService: PlaceMensaService) {} - - async ngOnInit() { - await this.getDishes(); - } - - async ngOnChanges(changes: SimpleChanges) { - if (typeof changes.items !== 'undefined') { - await this.getDishes(); - } - } - - /** - * Request dishes - */ - async getDishes() { - if (this.items) { - for (const item of this.items) { - const dishes = await this.mensaService.getAllDishes(item as SCPlace, 1); - this.dishes?.push(...dishes[Object.keys(dishes)[0]]); - } - } - } } 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 f5111e84..aec61fbf 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 @@ -1,5 +1,5 @@ - - - + + + + + + + + - -
- - {{ 'dashboard.canteens.no_favorite_prefix' | translate }} - {{ 'dashboard.canteens.no_favorite_link' | translate }} - {{ 'dashboard.canteens.no_favorite_suffix' | translate }} - -
-
-
+ + + + + {{ 'dashboard.canteens.no_favorite_prefix' | translate }} + {{ 'dashboard.canteens.no_favorite_link' | translate }} + {{ 'dashboard.canteens.no_favorite_suffix' | translate }} + + + + + diff --git a/src/app/modules/dashboard/sections/mensa-section/mensa-section.component.scss b/src/app/modules/dashboard/sections/mensa-section/mensa-section.component.scss index e69de29b..d52401dc 100644 --- a/src/app/modules/dashboard/sections/mensa-section/mensa-section.component.scss +++ b/src/app/modules/dashboard/sections/mensa-section/mensa-section.component.scss @@ -0,0 +1,28 @@ +/*! + * 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 . + */ + +stapps-mensa-section-content { + display: block; + margin-block-start: var(--spacing-md); +} + +.nothing-selected::part(native) { + background: none; + color: var(--ion-color-medium-shade); +} + +:host { + transition: height 150ms ease; +} diff --git a/src/app/modules/dashboard/sections/mensa-section/mensa-section.component.ts b/src/app/modules/dashboard/sections/mensa-section/mensa-section.component.ts index f223e978..f8043538 100644 --- a/src/app/modules/dashboard/sections/mensa-section/mensa-section.component.ts +++ b/src/app/modules/dashboard/sections/mensa-section/mensa-section.component.ts @@ -28,6 +28,7 @@ import {SettingsProvider} from '../../../settings/settings.provider'; import {FavoritesService} from '../../../favorites/favorites.service'; import {ContextMenuService} from '../../../menu/context/context-menu.service'; import {ConfigProvider} from '../../../config/config.provider'; +import {animate, style, transition, trigger} from '@angular/animations'; /** * Shows a section with meals of the chosen mensa @@ -36,6 +37,9 @@ import {ConfigProvider} from '../../../config/config.provider'; selector: 'stapps-mensa-section', templateUrl: 'mensa-section.component.html', styleUrls: ['mensa-section.component.scss'], + animations: [ + trigger('fade', [transition(':enter', [style({opacity: '0'}), animate(250, style({opacity: '1'}))])]), + ], }) export class MensaSectionComponent extends FoodDataListComponent { sub: Subscription; 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 e94672f0..f6641fc9 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 @@ -1,5 +1,5 @@
@@ -24,7 +24,7 @@ {{ 'data.detail.offers.sold_out' | translate }} -

+

{{ _offers[0].inPlace.name }}...

diff --git a/src/app/modules/data/list/data-list-item.component.ts b/src/app/modules/data/list/data-list-item.component.ts index d857ca4a..d2a926fa 100644 --- a/src/app/modules/data/list/data-list-item.component.ts +++ b/src/app/modules/data/list/data-list-item.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. @@ -12,7 +12,7 @@ * You should have received a copy of the GNU General Public License along with * this program. If not, see . */ -import {Component, ContentChild, Input, TemplateRef} from '@angular/core'; +import {Component, ContentChild, HostBinding, Input, TemplateRef} from '@angular/core'; import {SCThings} from '@openstapps/core'; import {DataRoutingService} from '../data-routing.service'; import {DataListContext} from './data-list.component'; @@ -40,8 +40,14 @@ export class DataListItemComponent { @Input() lines = 'inset'; + @Input() appearance: 'normal' | 'square' = 'normal'; + @ContentChild(TemplateRef) contentTemplateRef: TemplateRef>; + @HostBinding('class.square') get square() { + return this.appearance === 'square'; + } + constructor(private readonly dataRoutingService: DataRoutingService) {} /** diff --git a/src/app/modules/data/list/data-list-item.html b/src/app/modules/data/list/data-list-item.html index c3293d4e..7cd74600 100644 --- a/src/app/modules/data/list/data-list-item.html +++ b/src/app/modules/data/list/data-list-item.html @@ -112,7 +112,11 @@ >

- + diff --git a/src/app/modules/data/list/data-list-item.scss b/src/app/modules/data/list/data-list-item.scss index 852b8c8a..f6cfd7f0 100644 --- a/src/app/modules/data/list/data-list-item.scss +++ b/src/app/modules/data/list/data-list-item.scss @@ -41,3 +41,43 @@ ion-item { } } } + +:host.square ::ng-deep { + ion-item { + margin: 0; + } + + ion-row { + flex-direction: column; + justify-content: space-between; + height: 120px; + } + + ion-col { + flex-grow: 0; + flex-basis: min-content; + } + + .title { + display: -webkit-box; + white-space: break-spaces; + -webkit-box-orient: vertical; + -webkit-line-clamp: 3; + overflow: hidden; + } + + .title-sub { + display: none; + } + + // fix for Safari + stapps-offers-in-list { + position: absolute; + bottom: 0; + right: 0; + } + + stapps-offers-in-list .place { + display: none; + } +} diff --git a/src/app/modules/news/item/news-item.scss b/src/app/modules/news/item/news-item.scss index ff18fcb0..29a2f259 100644 --- a/src/app/modules/news/item/news-item.scss +++ b/src/app/modules/news/item/news-item.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. @@ -33,6 +33,10 @@ ion-card::part(native) { } ion-card-title { + display: -webkit-box; + -webkit-line-clamp: 3; + -webkit-box-orient: vertical; + overflow: hidden; font-size: var(--font-size-xl); --color: var(--ion-color-dark-contrast); } diff --git a/src/app/modules/news/news.module.ts b/src/app/modules/news/news.module.ts index 14b19451..96419e4a 100644 --- a/src/app/modules/news/news.module.ts +++ b/src/app/modules/news/news.module.ts @@ -1,16 +1,16 @@ /* - * 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 . */ import {CommonModule} from '@angular/common'; import {NgModule} from '@angular/core'; @@ -57,5 +57,6 @@ const newsRoutes: Routes = [{path: 'news', component: NewsPageComponent}]; UtilModule, ], providers: [SettingsProvider], + exports: [NewsItemComponent], }) export class NewsModule {} diff --git a/src/app/util/simple-swiper.component.ts b/src/app/util/simple-swiper.component.ts new file mode 100644 index 00000000..640cc1d5 --- /dev/null +++ b/src/app/util/simple-swiper.component.ts @@ -0,0 +1,27 @@ +/* + * 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 {Component, ContentChildren, ElementRef, ViewContainerRef} from '@angular/core'; + +@Component({ + selector: 'simple-swiper', + templateUrl: 'simple-swiper.html', + styleUrls: ['simple-swiper.scss'], +}) +export class SimpleSwiperComponent { + constructor(readonly viewContainerRef: ViewContainerRef) {} + + @ContentChildren('*') children: ElementRef; +} diff --git a/src/app/util/simple-swiper.html b/src/app/util/simple-swiper.html new file mode 100644 index 00000000..cc9f86ff --- /dev/null +++ b/src/app/util/simple-swiper.html @@ -0,0 +1,15 @@ + + diff --git a/src/app/util/simple-swiper.scss b/src/app/util/simple-swiper.scss new file mode 100644 index 00000000..1768aba4 --- /dev/null +++ b/src/app/util/simple-swiper.scss @@ -0,0 +1,54 @@ +/*! + * 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 { + position: relative; + display: grid; + grid-auto-flow: column; + + justify-content: start; + + scroll-snap-type: x mandatory; + overflow-x: auto; + overflow-y: hidden; + contain: layout; + + margin-inline: calc(-1 * var(--swiper-scroll-padding)); + + gap: var(--swiper-gap, 0); + + &::ng-deep > *:not(ion-button) { + contain: layout; + scroll-snap-align: start; + scroll-margin-inline: var(--swiper-scroll-padding, 0); + width: var(--swiper-slide-width); + + &:first-child { + padding-inline-start: var(--swiper-scroll-padding); + width: calc(var(--swiper-slide-width) + var(--swiper-scroll-padding)); + } + + &:last-child { + scroll-snap-align: end; + padding-inline-end: var(--swiper-scroll-padding); + width: calc(var(--swiper-slide-width) + var(--swiper-scroll-padding)); + } + } + + &::-webkit-scrollbar { + display: none; + } + scrollbar-width: none; +} diff --git a/src/app/util/util.module.ts b/src/app/util/util.module.ts index 44ed8a46..cc64ee50 100644 --- a/src/app/util/util.module.ts +++ b/src/app/util/util.module.ts @@ -27,6 +27,7 @@ import {TranslateModule} from '@ngx-translate/core'; 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'; @NgModule({ imports: [BrowserModule, IonicModule, TranslateModule, ThingTranslateModule.forChild()], @@ -41,6 +42,7 @@ import {ThingTranslateModule} from '../translation/thing-translate.module'; NextDateInListPipe, EditModalComponent, OpeningHoursComponent, + SimpleSwiperComponent, ], exports: [ ElementSizeChangeDirective, @@ -53,6 +55,7 @@ import {ThingTranslateModule} from '../translation/thing-translate.module'; NextDateInListPipe, EditModalComponent, OpeningHoursComponent, + SimpleSwiperComponent, ], }) export class UtilModule {}