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:
@@ -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>
|
||||
);
|
||||
}
|
||||
|
@@ -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>;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user