mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-28 12:32:59 +00:00
committed by
Rainer Killinger
parent
88684f068a
commit
e29a68bb03
@@ -82,6 +82,7 @@ import {CoordinatedSearchProvider} from './coordinated-search.provider';
|
|||||||
import {Geolocation} from '@ionic-native/geolocation/ngx';
|
import {Geolocation} from '@ionic-native/geolocation/ngx';
|
||||||
import {FavoriteButtonComponent} from './elements/favorite-button.component';
|
import {FavoriteButtonComponent} from './elements/favorite-button.component';
|
||||||
import {SimpleDataListComponent} from './list/simple-data-list.component';
|
import {SimpleDataListComponent} from './list/simple-data-list.component';
|
||||||
|
import {TitleCardComponent} from './elements/title-card.component';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Module for handling data
|
* Module for handling data
|
||||||
@@ -137,6 +138,7 @@ import {SimpleDataListComponent} from './list/simple-data-list.component';
|
|||||||
VideoDetailContentComponent,
|
VideoDetailContentComponent,
|
||||||
VideoListItemComponent,
|
VideoListItemComponent,
|
||||||
SimpleDataListComponent,
|
SimpleDataListComponent,
|
||||||
|
TitleCardComponent,
|
||||||
],
|
],
|
||||||
entryComponents: [DataListComponent, SimpleDataListComponent],
|
entryComponents: [DataListComponent, SimpleDataListComponent],
|
||||||
imports: [
|
imports: [
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
<stapps-title-card [item]="item"> </stapps-title-card>
|
||||||
<div [ngSwitch]="item.type">
|
<div [ngSwitch]="item.type">
|
||||||
<stapps-article-detail-content
|
<stapps-article-detail-content
|
||||||
[item]="item"
|
[item]="item"
|
||||||
|
|||||||
21
src/app/modules/data/elements/title-card.component.css
Normal file
21
src/app/modules/data/elements/title-card.component.css
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.text-accordion {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
}
|
||||||
41
src/app/modules/data/elements/title-card.component.html
Normal file
41
src/app/modules/data/elements/title-card.component.html
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<!--
|
||||||
|
~ Copyright (C) 2021 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 <https://www.gnu.org/licenses/>.
|
||||||
|
-->
|
||||||
|
<ion-card>
|
||||||
|
<ion-card-content>
|
||||||
|
<ion-text color="dark">
|
||||||
|
<h1>
|
||||||
|
{{ 'name' | thingTranslate: item }}
|
||||||
|
</h1>
|
||||||
|
</ion-text>
|
||||||
|
<div *ngIf="item.description">
|
||||||
|
<br />
|
||||||
|
<div
|
||||||
|
class="text-accordion"
|
||||||
|
[style.-webkit-line-clamp]="descriptionLinesToDisplay"
|
||||||
|
#accordionTextArea
|
||||||
|
>
|
||||||
|
{{ 'description' | thingTranslate: item }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ion-card-content>
|
||||||
|
</ion-card>
|
||||||
|
<ion-button
|
||||||
|
expand="full"
|
||||||
|
fill="clear"
|
||||||
|
*ngIf="item.description && buttonShown"
|
||||||
|
(click)="toggleDescriptionAccordion()"
|
||||||
|
>
|
||||||
|
<ion-icon [name]="buttonState" size="large"></ion-icon>
|
||||||
|
</ion-button>
|
||||||
102
src/app/modules/data/elements/title-card.component.ts
Normal file
102
src/app/modules/data/elements/title-card.component.ts
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 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 <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {
|
||||||
|
Component,
|
||||||
|
ElementRef,
|
||||||
|
HostListener,
|
||||||
|
Input,
|
||||||
|
OnChanges,
|
||||||
|
OnInit,
|
||||||
|
ViewChild,
|
||||||
|
} from '@angular/core';
|
||||||
|
import {SCThings} from '@openstapps/core';
|
||||||
|
|
||||||
|
enum AccordionButtonState {
|
||||||
|
collapsed = 'chevron-down',
|
||||||
|
expanded = 'chevron-up',
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'stapps-title-card',
|
||||||
|
templateUrl: './title-card.component.html',
|
||||||
|
styleUrls: ['./title-card.component.css'],
|
||||||
|
})
|
||||||
|
export class TitleCardComponent implements OnInit, OnChanges {
|
||||||
|
/**
|
||||||
|
* The item whose title (and description) to display
|
||||||
|
*/
|
||||||
|
@Input() item: SCThings;
|
||||||
|
|
||||||
|
@ViewChild('accordionTextArea') accordionTextArea: ElementRef;
|
||||||
|
|
||||||
|
buttonState = AccordionButtonState.collapsed;
|
||||||
|
|
||||||
|
buttonShown = true;
|
||||||
|
|
||||||
|
descriptionLinesShown: number;
|
||||||
|
|
||||||
|
descriptionLinesTotal: number;
|
||||||
|
|
||||||
|
descriptionPreviewLines = 3;
|
||||||
|
|
||||||
|
descriptionLinesToDisplay = 0;
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
if (this.item.description) {
|
||||||
|
this.descriptionLinesToDisplay = this.descriptionPreviewLines;
|
||||||
|
setTimeout(() => this.checkTextElipsis(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnChanges() {
|
||||||
|
this.checkTextElipsis();
|
||||||
|
}
|
||||||
|
|
||||||
|
@HostListener('window:resize', ['$event'])
|
||||||
|
checkTextElipsis() {
|
||||||
|
if (typeof this.accordionTextArea === 'undefined') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const element = this.accordionTextArea.nativeElement as HTMLElement;
|
||||||
|
|
||||||
|
const lineHeight = Number.parseInt(
|
||||||
|
getComputedStyle(element).getPropertyValue('line-height'),
|
||||||
|
);
|
||||||
|
this.descriptionLinesTotal = element?.scrollHeight / lineHeight;
|
||||||
|
this.descriptionLinesShown = element?.offsetHeight / lineHeight;
|
||||||
|
if (this.buttonState === AccordionButtonState.expanded) {
|
||||||
|
this.descriptionLinesToDisplay = this.descriptionLinesTotal;
|
||||||
|
}
|
||||||
|
const isElipsed = element?.offsetHeight < element?.scrollHeight;
|
||||||
|
this.buttonShown =
|
||||||
|
(isElipsed && this.buttonState === AccordionButtonState.collapsed) ||
|
||||||
|
(!isElipsed && this.buttonState === AccordionButtonState.expanded);
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleDescriptionAccordion() {
|
||||||
|
if (this.descriptionLinesToDisplay > 0) {
|
||||||
|
this.descriptionLinesToDisplay =
|
||||||
|
this.descriptionLinesToDisplay === this.descriptionPreviewLines
|
||||||
|
? this.descriptionLinesTotal
|
||||||
|
: this.descriptionPreviewLines;
|
||||||
|
}
|
||||||
|
this.buttonState =
|
||||||
|
this.buttonState === AccordionButtonState.collapsed
|
||||||
|
? AccordionButtonState.expanded
|
||||||
|
: AccordionButtonState.collapsed;
|
||||||
|
setTimeout(() => this.checkTextElipsis(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2019 StApps
|
* Copyright (C) 2019-2021 StApps
|
||||||
* This program is free software: you can redistribute it and/or modify it
|
* 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
|
* under the terms of the GNU General Public License as published by the Free
|
||||||
* Software Foundation, version 3.
|
* Software Foundation, version 3.
|
||||||
@@ -12,24 +12,10 @@
|
|||||||
* You should have received a copy of the GNU General Public License along with
|
* You should have received a copy of the GNU General Public License along with
|
||||||
* this program. If not, see <https://www.gnu.org/licenses/>.
|
* this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
import {
|
import {Component, Input, OnInit} from '@angular/core';
|
||||||
Component,
|
|
||||||
Input,
|
|
||||||
OnInit,
|
|
||||||
ViewChild,
|
|
||||||
ElementRef,
|
|
||||||
HostListener,
|
|
||||||
OnDestroy,
|
|
||||||
OnChanges,
|
|
||||||
} from '@angular/core';
|
|
||||||
import {SCCatalog, SCSearchBooleanFilter, SCDucetSort} from '@openstapps/core';
|
import {SCCatalog, SCSearchBooleanFilter, SCDucetSort} from '@openstapps/core';
|
||||||
import {SearchPageComponent} from '../../list/search-page.component';
|
import {SearchPageComponent} from '../../list/search-page.component';
|
||||||
|
|
||||||
enum AccordionButtonState {
|
|
||||||
collapsed = 'chevron-down',
|
|
||||||
expanded = 'chevron-up',
|
|
||||||
}
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'stapps-catalog-detail-content',
|
selector: 'stapps-catalog-detail-content',
|
||||||
templateUrl: 'catalog-detail-content.html',
|
templateUrl: 'catalog-detail-content.html',
|
||||||
@@ -37,37 +23,15 @@ enum AccordionButtonState {
|
|||||||
})
|
})
|
||||||
export class CatalogDetailContentComponent
|
export class CatalogDetailContentComponent
|
||||||
extends SearchPageComponent
|
extends SearchPageComponent
|
||||||
implements OnInit, OnDestroy, OnChanges
|
implements OnInit
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* SCCatalog to display
|
* SCCatalog to display
|
||||||
*/
|
*/
|
||||||
@Input() item: SCCatalog;
|
@Input() item: SCCatalog;
|
||||||
|
|
||||||
@ViewChild('accordionTextArea') accordionTextArea: ElementRef;
|
|
||||||
|
|
||||||
buttonState = AccordionButtonState.collapsed;
|
|
||||||
|
|
||||||
buttonShown = true;
|
|
||||||
|
|
||||||
descriptionLinesShown: number;
|
|
||||||
|
|
||||||
descriptionLinesTotal: number;
|
|
||||||
|
|
||||||
descriptionPreviewLines = 3;
|
|
||||||
|
|
||||||
descriptionLinesToDisplay = 0;
|
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
super.ngOnInit();
|
super.ngOnInit();
|
||||||
if (this.item.description) {
|
|
||||||
this.descriptionLinesToDisplay = this.descriptionPreviewLines;
|
|
||||||
setTimeout(() => this.checkTextElipsis(), 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnChanges() {
|
|
||||||
this.checkTextElipsis();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
initialize() {
|
initialize() {
|
||||||
@@ -141,39 +105,4 @@ export class CatalogDetailContentComponent
|
|||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@HostListener('window:resize', ['$event'])
|
|
||||||
checkTextElipsis() {
|
|
||||||
if (typeof this.accordionTextArea === 'undefined') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const element = this.accordionTextArea.nativeElement as HTMLElement;
|
|
||||||
|
|
||||||
const lineHeight = Number.parseInt(
|
|
||||||
getComputedStyle(element).getPropertyValue('line-height'),
|
|
||||||
);
|
|
||||||
this.descriptionLinesTotal = element?.scrollHeight / lineHeight;
|
|
||||||
this.descriptionLinesShown = element?.offsetHeight / lineHeight;
|
|
||||||
if (this.buttonState === AccordionButtonState.expanded) {
|
|
||||||
this.descriptionLinesToDisplay = this.descriptionLinesTotal;
|
|
||||||
}
|
|
||||||
const isElipsed = element?.offsetHeight < element?.scrollHeight;
|
|
||||||
this.buttonShown =
|
|
||||||
(isElipsed && this.buttonState === AccordionButtonState.collapsed) ||
|
|
||||||
(!isElipsed && this.buttonState === AccordionButtonState.expanded);
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleDescriptionAccordion() {
|
|
||||||
if (this.descriptionLinesToDisplay > 0) {
|
|
||||||
this.descriptionLinesToDisplay =
|
|
||||||
this.descriptionLinesToDisplay === this.descriptionPreviewLines
|
|
||||||
? this.descriptionLinesTotal
|
|
||||||
: this.descriptionPreviewLines;
|
|
||||||
}
|
|
||||||
this.buttonState =
|
|
||||||
this.buttonState === AccordionButtonState.collapsed
|
|
||||||
? AccordionButtonState.expanded
|
|
||||||
: AccordionButtonState.collapsed;
|
|
||||||
setTimeout(() => this.checkTextElipsis(), 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,30 +1,3 @@
|
|||||||
<ion-card>
|
|
||||||
<ion-card-content>
|
|
||||||
<ion-text color="dark">
|
|
||||||
<h1>
|
|
||||||
{{ 'name' | thingTranslate: item }}
|
|
||||||
</h1>
|
|
||||||
</ion-text>
|
|
||||||
<div *ngIf="item.description">
|
|
||||||
<br />
|
|
||||||
<div
|
|
||||||
class="text-accordion"
|
|
||||||
[style.-webkit-line-clamp]="descriptionLinesToDisplay"
|
|
||||||
#accordionTextArea
|
|
||||||
>
|
|
||||||
{{ 'description' | thingTranslate: item }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</ion-card-content>
|
|
||||||
</ion-card>
|
|
||||||
<ion-button
|
|
||||||
expand="full"
|
|
||||||
fill="clear"
|
|
||||||
*ngIf="item.description && buttonShown"
|
|
||||||
(click)="toggleDescriptionAccordion()"
|
|
||||||
>
|
|
||||||
<ion-icon [name]="buttonState" size="large"></ion-icon>
|
|
||||||
</ion-button>
|
|
||||||
<stapps-simple-data-list
|
<stapps-simple-data-list
|
||||||
id="simple-data-list"
|
id="simple-data-list"
|
||||||
[items]="items"
|
[items]="items"
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
.text-accordion {
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
display: -webkit-box;
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,13 +1,3 @@
|
|||||||
<ion-card>
|
|
||||||
<ion-card-content>
|
|
||||||
<ion-text color="dark">
|
|
||||||
<h1>
|
|
||||||
{{ 'name' | thingTranslate: item }}
|
|
||||||
</h1>
|
|
||||||
</ion-text>
|
|
||||||
{{ 'description' | thingTranslate: item }}
|
|
||||||
</ion-card-content>
|
|
||||||
</ion-card>
|
|
||||||
<ion-grid>
|
<ion-grid>
|
||||||
<ion-row>
|
<ion-row>
|
||||||
<ion-col>
|
<ion-col>
|
||||||
|
|||||||
@@ -1,13 +1,3 @@
|
|||||||
<ion-card>
|
|
||||||
<ion-card-content>
|
|
||||||
<ion-text color="dark">
|
|
||||||
<h1>
|
|
||||||
{{ 'name' | thingTranslate: item }}
|
|
||||||
</h1>
|
|
||||||
</ion-text>
|
|
||||||
{{ 'description' | thingTranslate: item }}</ion-card-content
|
|
||||||
>
|
|
||||||
</ion-card>
|
|
||||||
<ng-container>
|
<ng-container>
|
||||||
<div *ngIf="dishes | async as dishes; else loading">
|
<div *ngIf="dishes | async as dishes; else loading">
|
||||||
<ion-segment [(ngModel)]="selectedDay" mode="md">
|
<ion-segment [(ngModel)]="selectedDay" mode="md">
|
||||||
|
|||||||
Reference in New Issue
Block a user