mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-21 09:03:02 +00:00
171 lines
4.0 KiB
TypeScript
171 lines
4.0 KiB
TypeScript
/*
|
|
* 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 <https://www.gnu.org/licenses/>.
|
|
*/
|
|
import {Component, OnInit} from '@angular/core';
|
|
import {IonRefresher} from '@ionic/angular';
|
|
import {
|
|
SCMessage,
|
|
SCSearchFilter,
|
|
SCSearchValueFilter,
|
|
SCSetting,
|
|
} from '@openstapps/core';
|
|
import {SettingsProvider} from '../../settings/settings.provider';
|
|
import {
|
|
newsFilterSettingsCategory,
|
|
newsFilterSettingsFieldsMapping,
|
|
NewsFilterSettingsNames,
|
|
} from '../news-filter-settings';
|
|
import {NewsProvider} from '../news.provider';
|
|
import {SplashScreen} from '@capacitor/splash-screen';
|
|
|
|
/**
|
|
* News page component
|
|
*/
|
|
@Component({
|
|
selector: 'stapps-news-page',
|
|
templateUrl: 'news-page.html',
|
|
styleUrls: ['news-page.scss'],
|
|
})
|
|
export class NewsPageComponent implements OnInit {
|
|
/**
|
|
* Thing counter to start query the next page from
|
|
*/
|
|
from = 0;
|
|
|
|
/**
|
|
* News (messages) to show
|
|
*/
|
|
news: SCMessage[] = [];
|
|
|
|
/**
|
|
* Minimum page size of queries
|
|
*/
|
|
minPageSize = 10;
|
|
|
|
/**
|
|
* Page size of queries
|
|
*/
|
|
pageSize = 10;
|
|
|
|
/**
|
|
* Element size in px
|
|
*/
|
|
elementSize = [300, 300];
|
|
|
|
/**
|
|
* Relevant settings
|
|
*/
|
|
settings: SCSetting[];
|
|
|
|
/**
|
|
* Active filters
|
|
*/
|
|
filters: SCSearchFilter[];
|
|
|
|
constructor(
|
|
private newsProvider: NewsProvider,
|
|
private settingsProvider: SettingsProvider,
|
|
) {}
|
|
|
|
/**
|
|
* Fetch news from the backend
|
|
*/
|
|
async fetchNews() {
|
|
this.from = this.pageSize;
|
|
this.news = await this.newsProvider.getList(this.pageSize, 0, [
|
|
...this.filters,
|
|
]);
|
|
|
|
await SplashScreen.hide();
|
|
}
|
|
|
|
/**
|
|
* Loads more news
|
|
*/
|
|
async loadMore(
|
|
infiniteScrollElement?: HTMLIonInfiniteScrollElement,
|
|
more = this.pageSize,
|
|
): Promise<void> {
|
|
const from = this.from;
|
|
this.from += more;
|
|
const fetchedNews = await this.newsProvider.getList(this.pageSize, from, [
|
|
...this.filters,
|
|
]);
|
|
|
|
this.news = [...this.news, ...fetchedNews];
|
|
await infiniteScrollElement?.complete();
|
|
}
|
|
|
|
calcPageSize(entry: ResizeObserverEntry) {
|
|
this.pageSize = Math.max(
|
|
this.minPageSize,
|
|
Math.floor(entry.contentRect.width / this.elementSize[0]) *
|
|
Math.ceil(entry.contentRect.height / this.elementSize[1] + 0.25),
|
|
);
|
|
if (!this.from || this.from === 0) return;
|
|
const more = Math.max(0, this.pageSize - this.from);
|
|
if (more !== 0) {
|
|
void this.loadMore(undefined, Math.max(more, this.minPageSize));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Initialize the local variables on component initialization
|
|
*/
|
|
async ngOnInit() {
|
|
// Helper method to provide the relevant settings
|
|
const getNewsSettings = async (settingNames: NewsFilterSettingsNames[]) => {
|
|
const settings = [];
|
|
for (const settingName of settingNames) {
|
|
settings.push(
|
|
await this.settingsProvider.getSetting(
|
|
newsFilterSettingsCategory,
|
|
settingName,
|
|
),
|
|
);
|
|
}
|
|
return settings;
|
|
};
|
|
|
|
this.settings = await getNewsSettings(
|
|
Object.keys(newsFilterSettingsFieldsMapping) as NewsFilterSettingsNames[],
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Updates the shown list
|
|
*
|
|
* @param refresher Refresher component that triggers the update
|
|
*/
|
|
async refresh(refresher: IonRefresher) {
|
|
try {
|
|
await this.fetchNews();
|
|
} catch {
|
|
this.news = [];
|
|
} finally {
|
|
await refresher.complete();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Executed when filters have been changed
|
|
*
|
|
* @param filters Current filters to be used
|
|
*/
|
|
toggleFilter(filters: SCSearchValueFilter[]) {
|
|
this.filters = filters;
|
|
void this.fetchNews();
|
|
}
|
|
}
|