From 249b3a186e2957d353f6f9e6223b3e3c47aec95a Mon Sep 17 00:00:00 2001 From: Dessalines Date: Tue, 14 Apr 2020 19:18:13 -0400 Subject: [PATCH] Front end federation names and links for users, posts, and communities. --- server/src/api/community.rs | 11 ++----- server/src/apub/mod.rs | 10 ------- server/src/settings.rs | 2 +- ui/src/components/admin-settings.tsx | 6 ++++ ui/src/components/comment-node.tsx | 3 ++ ui/src/components/communities.tsx | 5 ++-- ui/src/components/community-link.tsx | 35 ++++++++++++++++++++++ ui/src/components/community.tsx | 5 ++++ ui/src/components/main.tsx | 17 ++++++++--- ui/src/components/post-form.tsx | 7 ++++- ui/src/components/post-listing.tsx | 21 +++++++------ ui/src/components/private-message-form.tsx | 3 ++ ui/src/components/sidebar.tsx | 32 ++++++++++++++------ ui/src/components/user-listing.tsx | 20 +++++++++++-- ui/src/components/user.tsx | 13 +++++--- ui/src/env.ts | 2 +- 16 files changed, 138 insertions(+), 54 deletions(-) create mode 100644 ui/src/components/community-link.tsx diff --git a/server/src/api/community.rs b/server/src/api/community.rs index 35ca1d260..40d8afe39 100644 --- a/server/src/api/community.rs +++ b/server/src/api/community.rs @@ -1,9 +1,8 @@ use super::*; 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 std::str::FromStr; -use url::Url; #[derive(Serialize, Deserialize)] pub struct GetCommunity { @@ -144,7 +143,7 @@ impl Perform for Oper { } }; - 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, Err(_e) => return Err(APIError::err("couldnt_find_community").into()), }; @@ -160,12 +159,6 @@ impl Perform for Oper { let creator_user = admins.remove(creator_index); 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 Ok(GetCommunityResponse { community: community_view, diff --git a/server/src/apub/mod.rs b/server/src/apub/mod.rs index c1716ca27..b2d157ae8 100644 --- a/server/src/apub/mod.rs +++ b/server/src/apub/mod.rs @@ -92,16 +92,6 @@ fn vec_bytes_to_str(bytes: Vec) -> String { 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 { Settings::get() .federation diff --git a/server/src/settings.rs b/server/src/settings.rs index 8c3cd6a12..d9d7a2291 100644 --- a/server/src/settings.rs +++ b/server/src/settings.rs @@ -60,7 +60,7 @@ pub struct Database { pub pool_size: u32, } -#[derive(Debug, Deserialize)] +#[derive(Debug, Deserialize, Clone)] pub struct Federation { pub enabled: bool, pub followed_instances: String, diff --git a/ui/src/components/admin-settings.tsx b/ui/src/components/admin-settings.tsx index 56af71149..0034c229e 100644 --- a/ui/src/components/admin-settings.tsx +++ b/ui/src/components/admin-settings.tsx @@ -113,6 +113,9 @@ export class AdminSettings extends Component { user={{ name: admin.name, avatar: admin.avatar, + id: admin.id, + local: admin.local, + actor_id: admin.actor_id, }} /> @@ -133,6 +136,9 @@ export class AdminSettings extends Component { user={{ name: banned.name, avatar: banned.avatar, + id: banned.id, + local: banned.local, + actor_id: banned.actor_id, }} /> diff --git a/ui/src/components/comment-node.tsx b/ui/src/components/comment-node.tsx index 69a78f501..9bc9c7bbb 100644 --- a/ui/src/components/comment-node.tsx +++ b/ui/src/components/comment-node.tsx @@ -154,6 +154,9 @@ export class CommentNode extends Component { user={{ name: node.comment.creator_name, avatar: node.comment.creator_avatar, + id: node.comment.creator_id, + local: node.comment.creator_local, + actor_id: node.comment.creator_actor_id, }} /> diff --git a/ui/src/components/communities.tsx b/ui/src/components/communities.tsx index 8d130ae71..a3e340ff9 100644 --- a/ui/src/components/communities.tsx +++ b/ui/src/components/communities.tsx @@ -14,6 +14,7 @@ import { } from '../interfaces'; import { WebSocketService } from '../services'; import { wsJsonToRes, toast } from '../utils'; +import { CommunityLink } from './community-link'; import { i18n } from '../i18next'; declare const Sortable: any; @@ -104,9 +105,7 @@ export class Communities extends Component { {this.state.communities.map(community => ( - - {community.name} - + {community.title} {community.category_name} diff --git a/ui/src/components/community-link.tsx b/ui/src/components/community-link.tsx new file mode 100644 index 000000000..bcfa05344 --- /dev/null +++ b/ui/src/components/community-link.tsx @@ -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 { + 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 {name_}; + } +} diff --git a/ui/src/components/community.tsx b/ui/src/components/community.tsx index a921de2c1..373d8f807 100644 --- a/ui/src/components/community.tsx +++ b/ui/src/components/community.tsx @@ -80,6 +80,11 @@ export class Community extends Component { removed: null, nsfw: false, deleted: null, + local: null, + actor_id: null, + last_refreshed_at: null, + creator_actor_id: null, + creator_local: null, }, moderators: [], admins: [], diff --git a/ui/src/components/main.tsx b/ui/src/components/main.tsx index 366d3be8f..9e0c3a598 100644 --- a/ui/src/components/main.tsx +++ b/ui/src/components/main.tsx @@ -34,6 +34,7 @@ import { ListingTypeSelect } from './listing-type-select'; import { DataTypeSelect } from './data-type-select'; import { SiteForm } from './site-form'; import { UserListing } from './user-listing'; +import { CommunityLink } from './community-link'; import { wsJsonToRes, repoUrl, @@ -190,9 +191,14 @@ export class Main extends Component {
    {this.state.subscribedCommunities.map(community => (
  • - - {community.community_name} - +
  • ))}
@@ -228,7 +234,7 @@ export class Main extends Component {
    {this.state.trendingCommunities.map(community => (
  • - {community.name} +
  • ))}
@@ -319,6 +325,9 @@ export class Main extends Component { user={{ name: admin.name, avatar: admin.avatar, + local: admin.local, + actor_id: admin.actor_id, + id: admin.id, }} /> diff --git a/ui/src/components/post-form.tsx b/ui/src/components/post-form.tsx index 4dbc8b23a..f04910bee 100644 --- a/ui/src/components/post-form.tsx +++ b/ui/src/components/post-form.tsx @@ -35,6 +35,7 @@ import { setupTribute, setupTippy, emojiPicker, + hostname, } from '../utils'; import autosize from 'autosize'; import Tribute from 'tributejs/src/Tribute.js'; @@ -331,7 +332,11 @@ export class PostForm extends Component { onInput={linkEvent(this, this.handlePostCommunityChange)} > {this.state.communities.map(community => ( - + ))} diff --git a/ui/src/components/post-listing.tsx b/ui/src/components/post-listing.tsx index 497492010..6ebf54002 100644 --- a/ui/src/components/post-listing.tsx +++ b/ui/src/components/post-listing.tsx @@ -20,6 +20,7 @@ import { MomentTime } from './moment-time'; import { PostForm } from './post-form'; import { IFramelyCard } from './iframely-card'; import { UserListing } from './user-listing'; +import { CommunityLink } from './community-link'; import { md, mdToHtml, @@ -420,6 +421,9 @@ export class PostListing extends Component { user={{ name: post.creator_name, avatar: post.creator_avatar, + id: post.creator_id, + local: post.creator_local, + actor_id: post.creator_actor_id, }} /> {this.isMod && ( @@ -440,15 +444,14 @@ export class PostListing extends Component { {this.props.showCommunity && ( {i18n.t('to')} - {post.local ? ( - - {post.community_name} - - ) : ( - - {hostname(post.ap_id)}/{post.community_name} - - )} + )} diff --git a/ui/src/components/private-message-form.tsx b/ui/src/components/private-message-form.tsx index 14abacf62..586b867e0 100644 --- a/ui/src/components/private-message-form.tsx +++ b/ui/src/components/private-message-form.tsx @@ -135,6 +135,9 @@ export class PrivateMessageForm extends Component< user={{ name: this.state.recipient.name, avatar: this.state.recipient.avatar, + id: this.state.recipient.id, + local: this.state.recipient.local, + actor_id: this.state.recipient.actor_id, }} /> diff --git a/ui/src/components/sidebar.tsx b/ui/src/components/sidebar.tsx index 4b317aaa2..517669230 100644 --- a/ui/src/components/sidebar.tsx +++ b/ui/src/components/sidebar.tsx @@ -8,12 +8,7 @@ import { UserView, } from '../interfaces'; import { WebSocketService, UserService } from '../services'; -import { - mdToHtml, - getUnixTime, - pictshareAvatarThumbnail, - showAvatars, -} from '../utils'; +import { mdToHtml, getUnixTime, hostname } from '../utils'; import { CommunityForm } from './community-form'; import { UserListing } from './user-listing'; import { i18n } from '../i18next'; @@ -65,6 +60,15 @@ export class Sidebar extends Component { sidebar() { 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 (
@@ -82,9 +86,15 @@ export class Sidebar extends Component { )} - - /c/{community.name} - + {community.local ? ( + + {name_} + + ) : ( + + {name_} + + )}
    {this.canMod && ( <> @@ -210,11 +220,15 @@ export class Sidebar extends Component { user={{ name: mod.user_name, avatar: mod.avatar, + id: mod.user_id, + local: mod.user_local, + actor_id: mod.user_actor_id, }} /> ))}
+ {/* TODO the to= needs to be able to handle community_ids as well, since they're federated */} { render() { 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 ( - + {user.avatar && showAvatars() && ( { class="rounded-circle mr-2" /> )} - {user.name} + {name_} ); } diff --git a/ui/src/components/user.tsx b/ui/src/components/user.tsx index bf67a5fdc..b3e4542f5 100644 --- a/ui/src/components/user.tsx +++ b/ui/src/components/user.tsx @@ -40,6 +40,7 @@ import { setupTippy, } from '../utils'; import { PostListing } from './post-listing'; +import { UserListing } from './user-listing'; import { SortSelect } from './sort-select'; import { ListingTypeSelect } from './listing-type-select'; import { CommentNodes } from './comment-nodes'; @@ -81,7 +82,6 @@ export class User extends Component { user: { id: null, name: null, - fedi_name: null, published: null, number_of_posts: null, post_score: null, @@ -91,6 +91,8 @@ export class User extends Component { avatar: null, show_avatars: null, send_notifications_to_email: null, + actor_id: null, + local: null, }, user_id: null, username: null, @@ -399,7 +401,9 @@ export class User extends Component {