Skip to content

Commit

Permalink
chore: add boilerplate state and model
Browse files Browse the repository at this point in the history
  • Loading branch information
DavideIadeluca committed Jan 30, 2024
1 parent 6ef1d94 commit 9b404b9
Show file tree
Hide file tree
Showing 2 changed files with 141 additions and 0 deletions.
6 changes: 6 additions & 0 deletions js/src/common/models/Poll.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import app from 'flarum/forum/app';
import Model from 'flarum/common/Model';

export default class Poll extends Model {
//TMP
}
135 changes: 135 additions & 0 deletions js/src/forum/states/PollListState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import app from 'flarum/forum/app';
import PaginatedListState, { Page, PaginatedListParams, PaginatedListRequestParams } from 'flarum/common/states/PaginatedListState';
import Poll from '../models/Poll';
import { ApiResponsePlural } from 'flarum/common/Store';
import EventEmitter from 'flarum/common/utils/EventEmitter';

export interface PollListParams extends PaginatedListParams {
sort?: string;
}

const globalEventEmitter = new EventEmitter();

export default class PollListState<P extends PollListParams = PollListParams> extends PaginatedListState<Poll, P> {
protected extraPolls: Poll[] = [];
protected eventEmitter: EventEmitter;

constructor(params: P, page: number = 1) {
super(params, page, 20);

this.eventEmitter = globalEventEmitter.on('poll.deleted', this.deletePoll.bind(this));
}

get type(): string {
return 'polls';
}

requestParams(): PaginatedListRequestParams {
const params = {
include: ['user', 'lastPostedUser'],
filter: this.params.filter || {},
sort: this.sortMap()[this.params.sort ?? ''],
};

if (this.params.q) {
params.filter.q = this.params.q;
params.include.push('mostRelevantPoll', 'mostRelevantPoll.user');
}

return params;
}

protected loadPage(page: number = 1): Promise<ApiResponsePlural<Poll>> {
const preloadedPolls = app.preloadedApiDocument<Poll[]>();

if (preloadedPolls) {
this.initialLoading = false;

return Promise.resolve(preloadedPolls);
}

return super.loadPage(page);
}

clear(): void {
super.clear();

this.extraPolls = [];
}

/**
* Get a map of sort keys (which appear in the URL, and are used for
* translation) to the API sort value that they represent.
*/
sortMap() {
const map: any = {};

if (this.params.q) {
map.relevance = '';
}
map.newest = '-createdAt';
map.oldest = 'createdAt';

return map;
}

/**
* In the last request, has the user searched for a poll?
*/
isSearchResults(): boolean {
return !!this.params.q;
}

removePoll(poll: Poll): void {
this.eventEmitter.emit('poll.deleted', poll);
}

deletePoll(poll: Poll): void {
for (const page of this.pages) {
const index = page.items.indexOf(poll);

if (index !== -1) {
page.items.splice(index, 1);
break;
}
}

const index = this.extraPolls.indexOf(poll);

if (index !== -1) {
this.extraPolls.splice(index);
}

m.redraw();
}

/**
* Add a poll to the top of the list.
*/
addPoll(poll: Poll): void {
this.removePoll(poll);
this.extraPolls.unshift(poll);

m.redraw();
}

protected getAllItems(): Poll[] {
return this.extraPolls.concat(super.getAllItems());
}

public getPages(): Page<Poll>[] {
const pages = super.getPages();

if (this.extraPolls.length) {
return [
{
number: -1,
items: this.extraPolls,
},
...pages,
];
}

return pages;
}
}

0 comments on commit 9b404b9

Please sign in to comment.