mirror of
https://github.com/flarum/core.git
synced 2025-08-03 23:17:43 +02:00
feat: reusable component for showing IP address (#4187)
This commit is contained in:
38
framework/core/js/src/common/components/IPAddress.tsx
Normal file
38
framework/core/js/src/common/components/IPAddress.tsx
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import Component, { ComponentAttrs } from '../Component';
|
||||||
|
import ItemList from '../utils/ItemList';
|
||||||
|
import type Mithril from 'mithril';
|
||||||
|
|
||||||
|
export interface IIPAddressAttrs extends ComponentAttrs {
|
||||||
|
ip: string | undefined | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A component to wrap an IP address for display.
|
||||||
|
* Designed to be customizable for different use cases.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* <IPAddress ip="127.0.0.1" />
|
||||||
|
* @example
|
||||||
|
* <IPAddress ip={post.data.attributes.ipAddress} />
|
||||||
|
*/
|
||||||
|
export default class IPAddress<CustomAttrs extends IIPAddressAttrs = IIPAddressAttrs> extends Component<CustomAttrs> {
|
||||||
|
ip!: string;
|
||||||
|
|
||||||
|
oninit(vnode: Mithril.Vnode<CustomAttrs, this>) {
|
||||||
|
super.oninit(vnode);
|
||||||
|
|
||||||
|
this.ip = this.attrs.ip || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
view() {
|
||||||
|
return <span className="IPAddress">{this.viewItems().toArray()}</span>;
|
||||||
|
}
|
||||||
|
|
||||||
|
viewItems(): ItemList<Mithril.Children> {
|
||||||
|
const items = new ItemList<Mithril.Children>();
|
||||||
|
|
||||||
|
items.add('ip', <>{this.ip}</>, 100);
|
||||||
|
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
}
|
@@ -1,6 +1,7 @@
|
|||||||
import app from '../app';
|
import app from '../app';
|
||||||
import Component, { ComponentAttrs } from '../../common/Component';
|
import Component, { ComponentAttrs } from '../../common/Component';
|
||||||
import Button from '../../common/components/Button';
|
import Button from '../../common/components/Button';
|
||||||
|
import IPAddress from '../../common/components/IPAddress';
|
||||||
import humanTime from '../../common/helpers/humanTime';
|
import humanTime from '../../common/helpers/humanTime';
|
||||||
import ItemList from '../../common/utils/ItemList';
|
import ItemList from '../../common/utils/ItemList';
|
||||||
import LabelValue from '../../common/components/LabelValue';
|
import LabelValue from '../../common/components/LabelValue';
|
||||||
@@ -105,7 +106,12 @@ export default class AccessTokensList<CustomAttrs extends IAccessTokensListAttrs
|
|||||||
token.lastActivityAt() ? (
|
token.lastActivityAt() ? (
|
||||||
<>
|
<>
|
||||||
{humanTime(token.lastActivityAt())}
|
{humanTime(token.lastActivityAt())}
|
||||||
{token.lastIpAddress() && ` — ${token.lastIpAddress()}`}
|
{token.lastIpAddress() && (
|
||||||
|
<span>
|
||||||
|
{' '}
|
||||||
|
— <IPAddress ip={token.lastIpAddress()} />
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
{this.attrs.type === 'developer_token' && token.device() && (
|
{this.attrs.type === 'developer_token' && token.device() && (
|
||||||
<>
|
<>
|
||||||
{' '}
|
{' '}
|
||||||
|
@@ -2,6 +2,7 @@ import app from '../../forum/app';
|
|||||||
import Component, { type ComponentAttrs } from '../../common/Component';
|
import Component, { type ComponentAttrs } from '../../common/Component';
|
||||||
import humanTime from '../../common/helpers/humanTime';
|
import humanTime from '../../common/helpers/humanTime';
|
||||||
import fullTime from '../../common/helpers/fullTime';
|
import fullTime from '../../common/helpers/fullTime';
|
||||||
|
import IPAddress from '../../common/components/IPAddress';
|
||||||
import Post from '../../common/models/Post';
|
import Post from '../../common/models/Post';
|
||||||
import type Model from '../../common/Model';
|
import type Model from '../../common/Model';
|
||||||
import type User from '../../common/models/User';
|
import type User from '../../common/models/User';
|
||||||
@@ -51,7 +52,9 @@ export default class PostMeta<CustomAttrs extends IPostMetaAttrs = IPostMetaAttr
|
|||||||
{!!permalink && (
|
{!!permalink && (
|
||||||
<div className="Dropdown-menu dropdown-menu">
|
<div className="Dropdown-menu dropdown-menu">
|
||||||
<span className="PostMeta-number">{this.postIdentifier(post)}</span> <span className="PostMeta-time">{fullTime(time)}</span>{' '}
|
<span className="PostMeta-number">{this.postIdentifier(post)}</span> <span className="PostMeta-time">{fullTime(time)}</span>{' '}
|
||||||
<span className="PostMeta-ip">{post.data.attributes!.ipAddress}</span>
|
<span className="PostMeta-ip">
|
||||||
|
<IPAddress ip={post.data.attributes?.ipAddress} />
|
||||||
|
</span>
|
||||||
{touch ? (
|
{touch ? (
|
||||||
<a className="Button PostMeta-permalink" href={permalink}>
|
<a className="Button PostMeta-permalink" href={permalink}>
|
||||||
{permalink}
|
{permalink}
|
||||||
|
Reference in New Issue
Block a user