mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-11-27 11:51:08 +00:00
Front end federation names and links for users, posts, and communities.
This commit is contained in:
parent
1336b4ed60
commit
fcf1c65fc1
16 changed files with 138 additions and 54 deletions
|
@ -1,9 +1,8 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::apub::activities::follow_community;
|
use crate::apub::activities::follow_community;
|
||||||
use crate::apub::{format_community_name, gen_keypair_str, make_apub_endpoint, EndpointType};
|
use crate::apub::{gen_keypair_str, make_apub_endpoint, EndpointType};
|
||||||
use diesel::PgConnection;
|
use diesel::PgConnection;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use url::Url;
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
pub struct GetCommunity {
|
pub struct GetCommunity {
|
||||||
|
@ -144,7 +143,7 @@ impl Perform<GetCommunityResponse> for Oper<GetCommunity> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut community_view = match CommunityView::read(&conn, community.id, user_id) {
|
let community_view = match CommunityView::read(&conn, community.id, user_id) {
|
||||||
Ok(community) => community,
|
Ok(community) => community,
|
||||||
Err(_e) => return Err(APIError::err("couldnt_find_community").into()),
|
Err(_e) => return Err(APIError::err("couldnt_find_community").into()),
|
||||||
};
|
};
|
||||||
|
@ -160,12 +159,6 @@ impl Perform<GetCommunityResponse> for Oper<GetCommunity> {
|
||||||
let creator_user = admins.remove(creator_index);
|
let creator_user = admins.remove(creator_index);
|
||||||
admins.insert(0, creator_user);
|
admins.insert(0, creator_user);
|
||||||
|
|
||||||
if !community.local {
|
|
||||||
let domain = Url::parse(&community.actor_id)?;
|
|
||||||
community_view.name =
|
|
||||||
format_community_name(&community_view.name.to_string(), domain.host_str().unwrap());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the jwt
|
// Return the jwt
|
||||||
Ok(GetCommunityResponse {
|
Ok(GetCommunityResponse {
|
||||||
community: community_view,
|
community: community_view,
|
||||||
|
|
|
@ -92,16 +92,6 @@ fn vec_bytes_to_str(bytes: Vec<u8>) -> String {
|
||||||
String::from_utf8_lossy(&bytes).into_owned()
|
String::from_utf8_lossy(&bytes).into_owned()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If community is on local instance, don't include the @instance part. This is only for displaying
|
|
||||||
/// to the user and should never be used otherwise.
|
|
||||||
pub fn format_community_name(name: &str, instance: &str) -> String {
|
|
||||||
if instance == Settings::get().hostname {
|
|
||||||
format!("!{}", name)
|
|
||||||
} else {
|
|
||||||
format!("!{}@{}", name, instance)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_following_instances() -> Vec<Instance> {
|
pub fn get_following_instances() -> Vec<Instance> {
|
||||||
Settings::get()
|
Settings::get()
|
||||||
.federation
|
.federation
|
||||||
|
|
|
@ -60,7 +60,7 @@ pub struct Database {
|
||||||
pub pool_size: u32,
|
pub pool_size: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize, Clone)]
|
||||||
pub struct Federation {
|
pub struct Federation {
|
||||||
pub enabled: bool,
|
pub enabled: bool,
|
||||||
pub followed_instances: String,
|
pub followed_instances: String,
|
||||||
|
|
6
ui/src/components/admin-settings.tsx
vendored
6
ui/src/components/admin-settings.tsx
vendored
|
@ -113,6 +113,9 @@ export class AdminSettings extends Component<any, AdminSettingsState> {
|
||||||
user={{
|
user={{
|
||||||
name: admin.name,
|
name: admin.name,
|
||||||
avatar: admin.avatar,
|
avatar: admin.avatar,
|
||||||
|
id: admin.id,
|
||||||
|
local: admin.local,
|
||||||
|
actor_id: admin.actor_id,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
|
@ -133,6 +136,9 @@ export class AdminSettings extends Component<any, AdminSettingsState> {
|
||||||
user={{
|
user={{
|
||||||
name: banned.name,
|
name: banned.name,
|
||||||
avatar: banned.avatar,
|
avatar: banned.avatar,
|
||||||
|
id: banned.id,
|
||||||
|
local: banned.local,
|
||||||
|
actor_id: banned.actor_id,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
|
|
3
ui/src/components/comment-node.tsx
vendored
3
ui/src/components/comment-node.tsx
vendored
|
@ -154,6 +154,9 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
|
||||||
user={{
|
user={{
|
||||||
name: node.comment.creator_name,
|
name: node.comment.creator_name,
|
||||||
avatar: node.comment.creator_avatar,
|
avatar: node.comment.creator_avatar,
|
||||||
|
id: node.comment.creator_id,
|
||||||
|
local: node.comment.creator_local,
|
||||||
|
actor_id: node.comment.creator_actor_id,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
|
|
5
ui/src/components/communities.tsx
vendored
5
ui/src/components/communities.tsx
vendored
|
@ -14,6 +14,7 @@ import {
|
||||||
} from '../interfaces';
|
} from '../interfaces';
|
||||||
import { WebSocketService } from '../services';
|
import { WebSocketService } from '../services';
|
||||||
import { wsJsonToRes, toast } from '../utils';
|
import { wsJsonToRes, toast } from '../utils';
|
||||||
|
import { CommunityLink } from './community-link';
|
||||||
import { i18n } from '../i18next';
|
import { i18n } from '../i18next';
|
||||||
|
|
||||||
declare const Sortable: any;
|
declare const Sortable: any;
|
||||||
|
@ -104,9 +105,7 @@ export class Communities extends Component<any, CommunitiesState> {
|
||||||
{this.state.communities.map(community => (
|
{this.state.communities.map(community => (
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<Link to={`/c/${community.name}`}>
|
<CommunityLink community={community} />
|
||||||
{community.name}
|
|
||||||
</Link>
|
|
||||||
</td>
|
</td>
|
||||||
<td class="d-none d-lg-table-cell">{community.title}</td>
|
<td class="d-none d-lg-table-cell">{community.title}</td>
|
||||||
<td>{community.category_name}</td>
|
<td>{community.category_name}</td>
|
||||||
|
|
35
ui/src/components/community-link.tsx
vendored
Normal file
35
ui/src/components/community-link.tsx
vendored
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
import { Component } from 'inferno';
|
||||||
|
import { Link } from 'inferno-router';
|
||||||
|
import { Community } from '../interfaces';
|
||||||
|
import { hostname } from '../utils';
|
||||||
|
|
||||||
|
interface CommunityOther {
|
||||||
|
name: string;
|
||||||
|
id?: number; // Necessary if its federated
|
||||||
|
local?: boolean;
|
||||||
|
actor_id?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CommunityLinkProps {
|
||||||
|
community: Community | CommunityOther;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CommunityLink extends Component<CommunityLinkProps, any> {
|
||||||
|
constructor(props: any, context: any) {
|
||||||
|
super(props, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let community = this.props.community;
|
||||||
|
let name_: string, link: string;
|
||||||
|
let local = community.local == null ? true : community.local;
|
||||||
|
if (local) {
|
||||||
|
name_ = community.name;
|
||||||
|
link = `/c/${community.name}`;
|
||||||
|
} else {
|
||||||
|
name_ = `${hostname(community.actor_id)}/${community.name}`;
|
||||||
|
link = `/community/${community.id}`;
|
||||||
|
}
|
||||||
|
return <Link to={link}>{name_}</Link>;
|
||||||
|
}
|
||||||
|
}
|
5
ui/src/components/community.tsx
vendored
5
ui/src/components/community.tsx
vendored
|
@ -80,6 +80,11 @@ export class Community extends Component<any, State> {
|
||||||
removed: null,
|
removed: null,
|
||||||
nsfw: false,
|
nsfw: false,
|
||||||
deleted: null,
|
deleted: null,
|
||||||
|
local: null,
|
||||||
|
actor_id: null,
|
||||||
|
last_refreshed_at: null,
|
||||||
|
creator_actor_id: null,
|
||||||
|
creator_local: null,
|
||||||
},
|
},
|
||||||
moderators: [],
|
moderators: [],
|
||||||
admins: [],
|
admins: [],
|
||||||
|
|
17
ui/src/components/main.tsx
vendored
17
ui/src/components/main.tsx
vendored
|
@ -34,6 +34,7 @@ import { ListingTypeSelect } from './listing-type-select';
|
||||||
import { DataTypeSelect } from './data-type-select';
|
import { DataTypeSelect } from './data-type-select';
|
||||||
import { SiteForm } from './site-form';
|
import { SiteForm } from './site-form';
|
||||||
import { UserListing } from './user-listing';
|
import { UserListing } from './user-listing';
|
||||||
|
import { CommunityLink } from './community-link';
|
||||||
import {
|
import {
|
||||||
wsJsonToRes,
|
wsJsonToRes,
|
||||||
repoUrl,
|
repoUrl,
|
||||||
|
@ -190,9 +191,14 @@ export class Main extends Component<any, MainState> {
|
||||||
<ul class="list-inline">
|
<ul class="list-inline">
|
||||||
{this.state.subscribedCommunities.map(community => (
|
{this.state.subscribedCommunities.map(community => (
|
||||||
<li class="list-inline-item">
|
<li class="list-inline-item">
|
||||||
<Link to={`/c/${community.community_name}`}>
|
<CommunityLink
|
||||||
{community.community_name}
|
community={{
|
||||||
</Link>
|
name: community.community_name,
|
||||||
|
id: community.community_id,
|
||||||
|
local: community.community_local,
|
||||||
|
actor_id: community.community_actor_id,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -228,7 +234,7 @@ export class Main extends Component<any, MainState> {
|
||||||
<ul class="list-inline">
|
<ul class="list-inline">
|
||||||
{this.state.trendingCommunities.map(community => (
|
{this.state.trendingCommunities.map(community => (
|
||||||
<li class="list-inline-item">
|
<li class="list-inline-item">
|
||||||
<Link to={`/c/${community.name}`}>{community.name}</Link>
|
<CommunityLink community={community} />
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -319,6 +325,9 @@ export class Main extends Component<any, MainState> {
|
||||||
user={{
|
user={{
|
||||||
name: admin.name,
|
name: admin.name,
|
||||||
avatar: admin.avatar,
|
avatar: admin.avatar,
|
||||||
|
local: admin.local,
|
||||||
|
actor_id: admin.actor_id,
|
||||||
|
id: admin.id,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
|
|
7
ui/src/components/post-form.tsx
vendored
7
ui/src/components/post-form.tsx
vendored
|
@ -35,6 +35,7 @@ import {
|
||||||
setupTribute,
|
setupTribute,
|
||||||
setupTippy,
|
setupTippy,
|
||||||
emojiPicker,
|
emojiPicker,
|
||||||
|
hostname,
|
||||||
} from '../utils';
|
} from '../utils';
|
||||||
import autosize from 'autosize';
|
import autosize from 'autosize';
|
||||||
import Tribute from 'tributejs/src/Tribute.js';
|
import Tribute from 'tributejs/src/Tribute.js';
|
||||||
|
@ -331,7 +332,11 @@ export class PostForm extends Component<PostFormProps, PostFormState> {
|
||||||
onInput={linkEvent(this, this.handlePostCommunityChange)}
|
onInput={linkEvent(this, this.handlePostCommunityChange)}
|
||||||
>
|
>
|
||||||
{this.state.communities.map(community => (
|
{this.state.communities.map(community => (
|
||||||
<option value={community.id}>{community.name}</option>
|
<option value={community.id}>
|
||||||
|
{community.local
|
||||||
|
? community.name
|
||||||
|
: `${hostname(community.actor_id)}/${community.name}`}
|
||||||
|
</option>
|
||||||
))}
|
))}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
21
ui/src/components/post-listing.tsx
vendored
21
ui/src/components/post-listing.tsx
vendored
|
@ -20,6 +20,7 @@ import { MomentTime } from './moment-time';
|
||||||
import { PostForm } from './post-form';
|
import { PostForm } from './post-form';
|
||||||
import { IFramelyCard } from './iframely-card';
|
import { IFramelyCard } from './iframely-card';
|
||||||
import { UserListing } from './user-listing';
|
import { UserListing } from './user-listing';
|
||||||
|
import { CommunityLink } from './community-link';
|
||||||
import {
|
import {
|
||||||
md,
|
md,
|
||||||
mdToHtml,
|
mdToHtml,
|
||||||
|
@ -420,6 +421,9 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
user={{
|
user={{
|
||||||
name: post.creator_name,
|
name: post.creator_name,
|
||||||
avatar: post.creator_avatar,
|
avatar: post.creator_avatar,
|
||||||
|
id: post.creator_id,
|
||||||
|
local: post.creator_local,
|
||||||
|
actor_id: post.creator_actor_id,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{this.isMod && (
|
{this.isMod && (
|
||||||
|
@ -440,15 +444,14 @@ export class PostListing extends Component<PostListingProps, PostListingState> {
|
||||||
{this.props.showCommunity && (
|
{this.props.showCommunity && (
|
||||||
<span>
|
<span>
|
||||||
<span> {i18n.t('to')} </span>
|
<span> {i18n.t('to')} </span>
|
||||||
{post.local ? (
|
<CommunityLink
|
||||||
<Link to={`/c/${post.community_name}`}>
|
community={{
|
||||||
{post.community_name}
|
name: post.community_name,
|
||||||
</Link>
|
id: post.community_id,
|
||||||
) : (
|
local: post.community_local,
|
||||||
<a href={post.community_actor_id} target="_blank">
|
actor_id: post.community_actor_id,
|
||||||
{hostname(post.ap_id)}/{post.community_name}
|
}}
|
||||||
</a>
|
/>
|
||||||
)}
|
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</li>
|
</li>
|
||||||
|
|
3
ui/src/components/private-message-form.tsx
vendored
3
ui/src/components/private-message-form.tsx
vendored
|
@ -135,6 +135,9 @@ export class PrivateMessageForm extends Component<
|
||||||
user={{
|
user={{
|
||||||
name: this.state.recipient.name,
|
name: this.state.recipient.name,
|
||||||
avatar: this.state.recipient.avatar,
|
avatar: this.state.recipient.avatar,
|
||||||
|
id: this.state.recipient.id,
|
||||||
|
local: this.state.recipient.local,
|
||||||
|
actor_id: this.state.recipient.actor_id,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
32
ui/src/components/sidebar.tsx
vendored
32
ui/src/components/sidebar.tsx
vendored
|
@ -8,12 +8,7 @@ import {
|
||||||
UserView,
|
UserView,
|
||||||
} from '../interfaces';
|
} from '../interfaces';
|
||||||
import { WebSocketService, UserService } from '../services';
|
import { WebSocketService, UserService } from '../services';
|
||||||
import {
|
import { mdToHtml, getUnixTime, hostname } from '../utils';
|
||||||
mdToHtml,
|
|
||||||
getUnixTime,
|
|
||||||
pictshareAvatarThumbnail,
|
|
||||||
showAvatars,
|
|
||||||
} from '../utils';
|
|
||||||
import { CommunityForm } from './community-form';
|
import { CommunityForm } from './community-form';
|
||||||
import { UserListing } from './user-listing';
|
import { UserListing } from './user-listing';
|
||||||
import { i18n } from '../i18next';
|
import { i18n } from '../i18next';
|
||||||
|
@ -65,6 +60,15 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
|
||||||
|
|
||||||
sidebar() {
|
sidebar() {
|
||||||
let community = this.props.community;
|
let community = this.props.community;
|
||||||
|
let name_: string, link: string;
|
||||||
|
|
||||||
|
if (community.local) {
|
||||||
|
name_ = community.name;
|
||||||
|
link = `/c/${community.name}`;
|
||||||
|
} else {
|
||||||
|
name_ = `${hostname(community.actor_id)}/${community.name}`;
|
||||||
|
link = community.actor_id;
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div class="card border-secondary mb-3">
|
<div class="card border-secondary mb-3">
|
||||||
|
@ -82,9 +86,15 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
|
||||||
</small>
|
</small>
|
||||||
)}
|
)}
|
||||||
</h5>
|
</h5>
|
||||||
<Link className="text-muted" to={`/c/${community.name}`}>
|
{community.local ? (
|
||||||
/c/{community.name}
|
<Link className="text-muted" to={link}>
|
||||||
</Link>
|
{name_}
|
||||||
|
</Link>
|
||||||
|
) : (
|
||||||
|
<a className="text-muted" href={link} target="_blank">
|
||||||
|
{name_}
|
||||||
|
</a>
|
||||||
|
)}
|
||||||
<ul class="list-inline mb-1 text-muted font-weight-bold">
|
<ul class="list-inline mb-1 text-muted font-weight-bold">
|
||||||
{this.canMod && (
|
{this.canMod && (
|
||||||
<>
|
<>
|
||||||
|
@ -210,11 +220,15 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
|
||||||
user={{
|
user={{
|
||||||
name: mod.user_name,
|
name: mod.user_name,
|
||||||
avatar: mod.avatar,
|
avatar: mod.avatar,
|
||||||
|
id: mod.user_id,
|
||||||
|
local: mod.user_local,
|
||||||
|
actor_id: mod.user_actor_id,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
|
{/* TODO the to= needs to be able to handle community_ids as well, since they're federated */}
|
||||||
<Link
|
<Link
|
||||||
class={`btn btn-sm btn-secondary btn-block mb-3 ${
|
class={`btn btn-sm btn-secondary btn-block mb-3 ${
|
||||||
(community.deleted || community.removed) && 'no-click'
|
(community.deleted || community.removed) && 'no-click'
|
||||||
|
|
20
ui/src/components/user-listing.tsx
vendored
20
ui/src/components/user-listing.tsx
vendored
|
@ -1,11 +1,14 @@
|
||||||
import { Component } from 'inferno';
|
import { Component } from 'inferno';
|
||||||
import { Link } from 'inferno-router';
|
import { Link } from 'inferno-router';
|
||||||
import { UserView } from '../interfaces';
|
import { UserView } from '../interfaces';
|
||||||
import { pictshareAvatarThumbnail, showAvatars } from '../utils';
|
import { pictshareAvatarThumbnail, showAvatars, hostname } from '../utils';
|
||||||
|
|
||||||
interface UserOther {
|
interface UserOther {
|
||||||
name: string;
|
name: string;
|
||||||
|
id?: number; // Necessary if its federated
|
||||||
avatar?: string;
|
avatar?: string;
|
||||||
|
local?: boolean;
|
||||||
|
actor_id?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface UserListingProps {
|
interface UserListingProps {
|
||||||
|
@ -19,8 +22,19 @@ export class UserListing extends Component<UserListingProps, any> {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let user = this.props.user;
|
let user = this.props.user;
|
||||||
|
let local = user.local == null ? true : user.local;
|
||||||
|
let name_: string, link: string;
|
||||||
|
|
||||||
|
if (local) {
|
||||||
|
name_ = user.name;
|
||||||
|
link = `/u/${user.name}`;
|
||||||
|
} else {
|
||||||
|
name_ = `${hostname(user.actor_id)}/${user.name}`;
|
||||||
|
link = `/user/${user.id}`;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Link className="text-body font-weight-bold" to={`/u/${user.name}`}>
|
<Link className="text-body font-weight-bold" to={link}>
|
||||||
{user.avatar && showAvatars() && (
|
{user.avatar && showAvatars() && (
|
||||||
<img
|
<img
|
||||||
height="32"
|
height="32"
|
||||||
|
@ -29,7 +43,7 @@ export class UserListing extends Component<UserListingProps, any> {
|
||||||
class="rounded-circle mr-2"
|
class="rounded-circle mr-2"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<span>{user.name}</span>
|
<span>{name_}</span>
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
13
ui/src/components/user.tsx
vendored
13
ui/src/components/user.tsx
vendored
|
@ -40,6 +40,7 @@ import {
|
||||||
setupTippy,
|
setupTippy,
|
||||||
} from '../utils';
|
} from '../utils';
|
||||||
import { PostListing } from './post-listing';
|
import { PostListing } from './post-listing';
|
||||||
|
import { UserListing } from './user-listing';
|
||||||
import { SortSelect } from './sort-select';
|
import { SortSelect } from './sort-select';
|
||||||
import { ListingTypeSelect } from './listing-type-select';
|
import { ListingTypeSelect } from './listing-type-select';
|
||||||
import { CommentNodes } from './comment-nodes';
|
import { CommentNodes } from './comment-nodes';
|
||||||
|
@ -81,7 +82,6 @@ export class User extends Component<any, UserState> {
|
||||||
user: {
|
user: {
|
||||||
id: null,
|
id: null,
|
||||||
name: null,
|
name: null,
|
||||||
fedi_name: null,
|
|
||||||
published: null,
|
published: null,
|
||||||
number_of_posts: null,
|
number_of_posts: null,
|
||||||
post_score: null,
|
post_score: null,
|
||||||
|
@ -91,6 +91,8 @@ export class User extends Component<any, UserState> {
|
||||||
avatar: null,
|
avatar: null,
|
||||||
show_avatars: null,
|
show_avatars: null,
|
||||||
send_notifications_to_email: null,
|
send_notifications_to_email: null,
|
||||||
|
actor_id: null,
|
||||||
|
local: null,
|
||||||
},
|
},
|
||||||
user_id: null,
|
user_id: null,
|
||||||
username: null,
|
username: null,
|
||||||
|
@ -399,7 +401,9 @@ export class User extends Component<any, UserState> {
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5>
|
<h5>
|
||||||
<ul class="list-inline mb-0">
|
<ul class="list-inline mb-0">
|
||||||
<li className="list-inline-item">{user.name}</li>
|
<li className="list-inline-item">
|
||||||
|
<UserListing user={user} />
|
||||||
|
</li>
|
||||||
{user.banned && (
|
{user.banned && (
|
||||||
<li className="list-inline-item badge badge-danger">
|
<li className="list-inline-item badge badge-danger">
|
||||||
{i18n.t('banned')}
|
{i18n.t('banned')}
|
||||||
|
@ -455,8 +459,9 @@ export class User extends Component<any, UserState> {
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<a
|
<a
|
||||||
className={`btn btn-block btn-secondary mt-3 ${!this.state
|
className={`btn btn-block btn-secondary mt-3 ${
|
||||||
.user.matrix_user_id && 'disabled'}`}
|
!this.state.user.matrix_user_id && 'disabled'
|
||||||
|
}`}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
href={`https://matrix.to/#/${this.state.user.matrix_user_id}`}
|
href={`https://matrix.to/#/${this.state.user.matrix_user_id}`}
|
||||||
>
|
>
|
||||||
|
|
2
ui/src/env.ts
vendored
2
ui/src/env.ts
vendored
|
@ -1,6 +1,6 @@
|
||||||
const host = `${window.location.hostname}`;
|
const host = `${window.location.hostname}`;
|
||||||
const port = `${
|
const port = `${
|
||||||
window.location.port == '4444' ? '8536' : window.location.port
|
window.location.port == '4444' ? '8540' : window.location.port
|
||||||
}`;
|
}`;
|
||||||
const endpoint = `${host}:${port}`;
|
const endpoint = `${host}:${port}`;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue