1
0
mirror of https://github.com/flarum/core.git synced 2025-08-05 16:07:34 +02:00

chore: extensibility improvements (#3729)

* chore: improve tags page extensibility
* chore: improve discussion list item extensibility
* chore: improve change password modal extensibility
* chore: item-listify tags page
* chore: item-listify change email modal
* chore: simplify data flow

Signed-off-by: Sami Mazouz <sychocouldy@gmail.com>
This commit is contained in:
Sami Mazouz
2023-04-16 21:05:23 +01:00
committed by GitHub
parent 8b11fef3ee
commit b89a01c010
5 changed files with 291 additions and 174 deletions

View File

@@ -34,7 +34,8 @@ export default function tagLabel(tag, attrs = {}) {
link ? Link : 'span',
attrs,
<span className="TagLabel-text">
{tag && tag.icon() && tagIcon(tag, {}, { useColor: false })} {tagText}
{tag && tag.icon() && tagIcon(tag, { className: 'TagLabel-icon' }, { useColor: false })}
<span className="TagLabel-name">{tagText}</span>
</span>
);
}

View File

@@ -3,6 +3,7 @@ import IndexPage from 'flarum/forum/components/IndexPage';
import Link from 'flarum/common/components/Link';
import LoadingIndicator from 'flarum/common/components/LoadingIndicator';
import listItems from 'flarum/common/helpers/listItems';
import ItemList from 'flarum/common/utils/ItemList';
import humanTime from 'flarum/common/helpers/humanTime';
import textContrastClass from 'flarum/common/helpers/textContrastClass';
import classList from 'flarum/common/utils/classList';
@@ -37,69 +38,107 @@ export default class TagsPage extends Page {
});
}
view() {
if (this.loading) {
return <LoadingIndicator />;
}
const pinned = this.tags.filter((tag) => tag.position() !== null);
const cloud = this.tags.filter((tag) => tag.position() === null);
return (
<div className="TagsPage">
{IndexPage.prototype.hero()}
<div className="container">
<nav className="TagsPage-nav IndexPage-nav sideNav">
<ul>{listItems(IndexPage.prototype.sidebarItems().toArray())}</ul>
</nav>
<div className="TagsPage-content sideNavOffset">
<ul className="TagTiles">
{pinned.map((tag) => {
const lastPostedDiscussion = tag.lastPostedDiscussion();
const children = sortTags(tag.children() || []);
return (
<li className={classList('TagTile', { colored: tag.color() }, textContrastClass(tag.color()))} style={{ '--tag-bg': tag.color() }}>
<Link className="TagTile-info" href={app.route.tag(tag)}>
{tag.icon() && tagIcon(tag, {}, { useColor: false })}
<h3 className="TagTile-name">{tag.name()}</h3>
<p className="TagTile-description">{tag.description()}</p>
{children ? (
<div className="TagTile-children">
{children.map((child) => [<Link href={app.route.tag(child)}>{child.name()}</Link>, ' '])}
</div>
) : (
''
)}
</Link>
{lastPostedDiscussion ? (
<Link
className="TagTile-lastPostedDiscussion"
href={app.route.discussion(lastPostedDiscussion, lastPostedDiscussion.lastPostNumber())}
>
<span className="TagTile-lastPostedDiscussion-title">{lastPostedDiscussion.title()}</span>
{humanTime(lastPostedDiscussion.lastPostedAt())}
</Link>
) : (
<span className="TagTile-lastPostedDiscussion" />
)}
</li>
);
})}
</ul>
{cloud.length ? <div className="TagCloud">{cloud.map((tag) => [tagLabel(tag, { link: true }), ' '])}</div> : ''}
</div>
</div>
</div>
);
}
oncreate(vnode) {
super.oncreate(vnode);
app.setTitle(app.translator.trans('flarum-tags.forum.all_tags.meta_title_text'));
app.setTitleCount(0);
}
view() {
return <div className="TagsPage">{this.pageContent().toArray()}</div>;
}
pageContent() {
const items = new ItemList();
items.add('hero', this.hero(), 100);
items.add('main', <div className="container">{this.mainContent().toArray()}</div>, 10);
return items;
}
mainContent() {
const items = new ItemList();
items.add('sidebar', this.sidebar(), 100);
items.add('content', this.content(), 10);
return items;
}
content() {
return <div className="TagsPage-content sideNavOffset">{this.contentItems().toArray()}</div>;
}
contentItems() {
const items = new ItemList();
if (this.loading) {
items.add('loading', <LoadingIndicator />);
} else {
const pinned = this.tags.filter((tag) => tag.position() !== null);
const cloud = this.tags.filter((tag) => tag.position() === null);
items.add('tagTiles', this.tagTileListView(pinned), 100);
if (cloud.length) {
items.add('cloud', this.cloudView(cloud), 10);
}
}
return items;
}
hero() {
return IndexPage.prototype.hero();
}
sidebar() {
return (
<nav className="TagsPage-nav IndexPage-nav sideNav">
<ul>{listItems(this.sidebarItems().toArray())}</ul>
</nav>
);
}
sidebarItems() {
return IndexPage.prototype.sidebarItems();
}
tagTileListView(pinned) {
return <ul className="TagTiles">{pinned.map(this.tagTileView.bind(this))}</ul>;
}
tagTileView(tag) {
const lastPostedDiscussion = tag.lastPostedDiscussion();
const children = sortTags(tag.children() || []);
return (
<li className={classList('TagTile', { colored: tag.color() }, textContrastClass(tag.color()))} style={{ '--tag-bg': tag.color() }}>
<Link className="TagTile-info" href={app.route.tag(tag)}>
{tag.icon() && tagIcon(tag, {}, { useColor: false })}
<h3 className="TagTile-name">{tag.name()}</h3>
<p className="TagTile-description">{tag.description()}</p>
{children ? (
<div className="TagTile-children">{children.map((child) => [<Link href={app.route.tag(child)}>{child.name()}</Link>, ' '])}</div>
) : (
''
)}
</Link>
{lastPostedDiscussion ? (
<Link className="TagTile-lastPostedDiscussion" href={app.route.discussion(lastPostedDiscussion, lastPostedDiscussion.lastPostNumber())}>
<span className="TagTile-lastPostedDiscussion-title">{lastPostedDiscussion.title()}</span>
{humanTime(lastPostedDiscussion.lastPostedAt())}
</Link>
) : (
<span className="TagTile-lastPostedDiscussion" />
)}
</li>
);
}
cloudView(cloud) {
return <div className="TagCloud">{cloud.map((tag) => [tagLabel(tag, { link: true }), ' '])}</div>;
}
}