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

feat: improve extensibility of PostMeta component (#4196)

* refactor(core): create new method for selecting permalink

* refactor(core): improve extensibility of `PostMeta`

* chore: dummy commit
This commit is contained in:
Davide Iadeluca
2025-02-21 09:40:44 +01:00
committed by GitHub
parent 7feab89cca
commit 236a8e9e0a

View File

@@ -7,6 +7,8 @@ import Post from '../../common/models/Post';
import type Model from '../../common/Model';
import type User from '../../common/models/User';
import classList from '../../common/utils/classList';
import ItemList from '../../common/utils/ItemList';
import type Mithril from 'mithril';
type ModelType =
| Post
@@ -25,49 +27,69 @@ export interface IPostMetaAttrs extends ComponentAttrs {
*/
export default class PostMeta<CustomAttrs extends IPostMetaAttrs = IPostMetaAttrs> extends Component<CustomAttrs> {
view() {
return <div className="Dropdown PostMeta">{this.viewItems().toArray()}</div>;
}
viewItems(): ItemList<Mithril.Children> {
const items = new ItemList<Mithril.Children>();
const post = this.attrs.post;
const permalink = this.getPermalink(post);
const time = post.createdAt();
items.add(
'time',
<button
className={classList({
'Button Button--text': true,
'Dropdown-toggle Button--link': !!permalink,
})}
onclick={permalink ? this.selectPermalink.bind(this) : undefined}
data-toggle="dropdown"
>
{humanTime(time)}
</button>,
100
);
items.add('meta-dropdown', !!permalink && <div className="Dropdown-menu dropdown-menu">{this.metaItems().toArray()}</div>, 90);
return items;
}
metaItems(): ItemList<Mithril.Children> {
const items = new ItemList<Mithril.Children>();
const post = this.attrs.post;
const time = post.createdAt();
const permalink = this.getPermalink(post);
const touch = 'ontouchstart' in document.documentElement;
// When the dropdown menu is shown, select the contents of the permalink
// input so that the user can quickly copy the URL.
const selectPermalink = function (this: Element, e: MouseEvent) {
setTimeout(() => $(this).parent().find('.PostMeta-permalink').select());
items.add('post-number', <span className="PostMeta-number">{this.postIdentifier(post)}</span>, 100);
e.redraw = false;
};
items.add('post-time', <span className="PostMeta-time">{fullTime(time)}</span>, 90);
return (
<div className="Dropdown PostMeta">
<button
className={classList({
'Button Button--text': true,
'Dropdown-toggle Button--link': !!permalink,
})}
onclick={permalink ? selectPermalink : undefined}
data-toggle="dropdown"
>
{humanTime(time)}
</button>
{!!permalink && (
<div className="Dropdown-menu dropdown-menu">
<span className="PostMeta-number">{this.postIdentifier(post)}</span> <span className="PostMeta-time">{fullTime(time)}</span>{' '}
<span className="PostMeta-ip">
<IPAddress ip={post.ipAddress?.()} />
</span>
{touch ? (
<a className="Button PostMeta-permalink" href={permalink}>
{permalink}
</a>
) : (
<input className="FormControl PostMeta-permalink" value={permalink} onclick={(e: MouseEvent) => e.stopPropagation()} />
)}
</div>
)}
</div>
items.add(
'post-ip',
<span className="PostMeta-ip">
<IPAddress ip={post.ipAddress?.()} />
</span>,
80
);
items.add(
'permalink',
touch ? (
<a className="Button PostMeta-permalink" href={permalink}>
{permalink}
</a>
) : (
<input className="FormControl PostMeta-permalink" value={permalink} onclick={(e: MouseEvent) => e.stopPropagation()} />
),
0
);
return items;
}
/**
@@ -81,6 +103,15 @@ export default class PostMeta<CustomAttrs extends IPostMetaAttrs = IPostMetaAttr
return this.attrs.permalink?.() || null;
}
/**
* Selects the permalink input when the dropdown is shown.
*/
selectPermalink(e: MouseEvent) {
const $button = $(e.currentTarget as HTMLElement);
setTimeout(() => $button.parent().find('.PostMeta-permalink').select());
e.redraw = false;
}
postIdentifier(post: ModelType): string | null {
if (post instanceof Post) {
return app.translator.trans('core.forum.post.number_tooltip', { number: post.number() }, true);