]> Untitled Git - lemmy.git/commitdiff
Front end federation names and links for users, posts, and communities.
authorDessalines <tyhou13@gmx.com>
Tue, 14 Apr 2020 23:18:13 +0000 (19:18 -0400)
committerDessalines <tyhou13@gmx.com>
Tue, 14 Apr 2020 23:18:13 +0000 (19:18 -0400)
16 files changed:
server/src/api/community.rs
server/src/apub/mod.rs
server/src/settings.rs
ui/src/components/admin-settings.tsx
ui/src/components/comment-node.tsx
ui/src/components/communities.tsx
ui/src/components/community-link.tsx [new file with mode: 0644]
ui/src/components/community.tsx
ui/src/components/main.tsx
ui/src/components/post-form.tsx
ui/src/components/post-listing.tsx
ui/src/components/private-message-form.tsx
ui/src/components/sidebar.tsx
ui/src/components/user-listing.tsx
ui/src/components/user.tsx
ui/src/env.ts

index 35ca1d260dac8ca1a4028339d2f420bc0496b16c..40d8afe39331bbfe0f90ee3957c086a9ea0cb26d 100644 (file)
@@ -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<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,
       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);
     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,
index c1716ca274464df0466a0d0d690a9bbf48f049f3..b2d157ae8e0c153d8a123f002d768432c6a7d595 100644 (file)
@@ -92,16 +92,6 @@ fn vec_bytes_to_str(bytes: Vec<u8>) -> 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<Instance> {
   Settings::get()
     .federation
index 8c3cd6a1251d035b7220a43f5e7440e266220767..d9d7a2291a388bbf623ea86b3ec9dff2c8304628 100644 (file)
@@ -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,
index 56af71149a7a40a7a331a6e12f872b89923fd990..0034c229e9129724937c057f62ff642e2380de4f 100644 (file)
@@ -113,6 +113,9 @@ export class AdminSettings extends Component<any, AdminSettingsState> {
                 user={{
                   name: admin.name,
                   avatar: admin.avatar,
+                  id: admin.id,
+                  local: admin.local,
+                  actor_id: admin.actor_id,
                 }}
               />
             </li>
@@ -133,6 +136,9 @@ export class AdminSettings extends Component<any, AdminSettingsState> {
                 user={{
                   name: banned.name,
                   avatar: banned.avatar,
+                  id: banned.id,
+                  local: banned.local,
+                  actor_id: banned.actor_id,
                 }}
               />
             </li>
index 69a78f5015a4b0a5db4c0e7ecb0e5693a4a66818..9bc9c7bbbbdc92a41ee17c026d35789bc0a3c513 100644 (file)
@@ -154,6 +154,9 @@ export class CommentNode extends Component<CommentNodeProps, CommentNodeState> {
                   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,
                   }}
                 />
               </span>
index 8d130ae7119bb2d20e63a90d72d5dc7cc94dc993..a3e340ff96672d49547af11dab9db0ed21b185b7 100644 (file)
@@ -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<any, CommunitiesState> {
                   {this.state.communities.map(community => (
                     <tr>
                       <td>
-                        <Link to={`/c/${community.name}`}>
-                          {community.name}
-                        </Link>
+                        <CommunityLink community={community} />
                       </td>
                       <td class="d-none d-lg-table-cell">{community.title}</td>
                       <td>{community.category_name}</td>
diff --git a/ui/src/components/community-link.tsx b/ui/src/components/community-link.tsx
new file mode 100644 (file)
index 0000000..bcfa053
--- /dev/null
@@ -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>;
+  }
+}
index a921de2c130fb258fb3ac7029cdb8341aad08652..373d8f807fefd902b5bacdc75ce6d4f2a1efddbf 100644 (file)
@@ -80,6 +80,11 @@ export class Community extends Component<any, State> {
       removed: null,
       nsfw: false,
       deleted: null,
+      local: null,
+      actor_id: null,
+      last_refreshed_at: null,
+      creator_actor_id: null,
+      creator_local: null,
     },
     moderators: [],
     admins: [],
index 366d3be8f1e408f962e40fcd0332fcee727d181f..9e0c3a598a52edb5455ef5ade51ecd0788801532 100644 (file)
@@ -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<any, MainState> {
                       <ul class="list-inline">
                         {this.state.subscribedCommunities.map(community => (
                           <li class="list-inline-item">
-                            <Link to={`/c/${community.community_name}`}>
-                              {community.community_name}
-                            </Link>
+                            <CommunityLink
+                              community={{
+                                name: community.community_name,
+                                id: community.community_id,
+                                local: community.community_local,
+                                actor_id: community.community_actor_id,
+                              }}
+                            />
                           </li>
                         ))}
                       </ul>
@@ -228,7 +234,7 @@ export class Main extends Component<any, MainState> {
         <ul class="list-inline">
           {this.state.trendingCommunities.map(community => (
             <li class="list-inline-item">
-              <Link to={`/c/${community.name}`}>{community.name}</Link>
+              <CommunityLink community={community} />
             </li>
           ))}
         </ul>
@@ -319,6 +325,9 @@ export class Main extends Component<any, MainState> {
                     user={{
                       name: admin.name,
                       avatar: admin.avatar,
+                      local: admin.local,
+                      actor_id: admin.actor_id,
+                      id: admin.id,
                     }}
                   />
                 </li>
index 4dbc8b23a314b3d7bdd3d3e538f659b3ecbba9c8..f04910bee2134f18633c3974096366854e3b78b0 100644 (file)
@@ -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<PostFormProps, PostFormState> {
                   onInput={linkEvent(this, this.handlePostCommunityChange)}
                 >
                   {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>
               </div>
index 497492010690049c18bc6b37156d558c32584821..6ebf5400244253ba5eea677fc544e5377b9251e2 100644 (file)
@@ -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<PostListingProps, PostListingState> {
                     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<PostListingProps, PostListingState> {
                   {this.props.showCommunity && (
                     <span>
                       <span> {i18n.t('to')} </span>
-                      {post.local ? (
-                        <Link to={`/c/${post.community_name}`}>
-                          {post.community_name}
-                        </Link>
-                      ) : (
-                        <a href={post.community_actor_id} target="_blank">
-                          {hostname(post.ap_id)}/{post.community_name}
-                        </a>
-                      )}
+                      <CommunityLink
+                        community={{
+                          name: post.community_name,
+                          id: post.community_id,
+                          local: post.community_local,
+                          actor_id: post.community_actor_id,
+                        }}
+                      />
                     </span>
                   )}
                 </li>
index 14abacf62086ca1e0fccab3a49275eabdf11bc4b..586b867e00111f8339c65bcaf26667809734bbf2 100644 (file)
@@ -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,
                     }}
                   />
                 </div>
index 4b317aaa29880c957072d38945e019279658eb5c..517669230f8c758309dd0b5d1f0008f9000d89e2 100644 (file)
@@ -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<SidebarProps, SidebarState> {
 
   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 (
       <div>
         <div class="card border-secondary mb-3">
@@ -82,9 +86,15 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
                 </small>
               )}
             </h5>
-            <Link className="text-muted" to={`/c/${community.name}`}>
-              /c/{community.name}
-            </Link>
+            {community.local ? (
+              <Link className="text-muted" to={link}>
+                {name_}
+              </Link>
+            ) : (
+              <a className="text-muted" href={link} target="_blank">
+                {name_}
+              </a>
+            )}
             <ul class="list-inline mb-1 text-muted font-weight-bold">
               {this.canMod && (
                 <>
@@ -210,11 +220,15 @@ export class Sidebar extends Component<SidebarProps, SidebarState> {
                     user={{
                       name: mod.user_name,
                       avatar: mod.avatar,
+                      id: mod.user_id,
+                      local: mod.user_local,
+                      actor_id: mod.user_actor_id,
                     }}
                   />
                 </li>
               ))}
             </ul>
+            {/* TODO the to= needs to be able to handle community_ids as well, since they're federated */}
             <Link
               class={`btn btn-sm btn-secondary btn-block mb-3 ${
                 (community.deleted || community.removed) && 'no-click'
index 1f136e006c8fec137d0103b2087e5876fa014a16..356c4d4847797436b96d3794217731383497c2ac 100644 (file)
@@ -1,11 +1,14 @@
 import { Component } from 'inferno';
 import { Link } from 'inferno-router';
 import { UserView } from '../interfaces';
-import { pictshareAvatarThumbnail, showAvatars } from '../utils';
+import { pictshareAvatarThumbnail, showAvatars, hostname } from '../utils';
 
 interface UserOther {
   name: string;
+  id?: number; // Necessary if its federated
   avatar?: string;
+  local?: boolean;
+  actor_id?: string;
 }
 
 interface UserListingProps {
@@ -19,8 +22,19 @@ export class UserListing extends Component<UserListingProps, any> {
 
   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 (
-      <Link className="text-body font-weight-bold" to={`/u/${user.name}`}>
+      <Link className="text-body font-weight-bold" to={link}>
         {user.avatar && showAvatars() && (
           <img
             height="32"
@@ -29,7 +43,7 @@ export class UserListing extends Component<UserListingProps, any> {
             class="rounded-circle mr-2"
           />
         )}
-        <span>{user.name}</span>
+        <span>{name_}</span>
       </Link>
     );
   }
index bf67a5fdc204fcef9b35af82443abdd59719be8d..b3e4542f548e2a03e2216c48766ec15eb3d42af4 100644 (file)
@@ -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<any, UserState> {
     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<any, UserState> {
       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<any, UserState> {
           <div class="card-body">
             <h5>
               <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 && (
                   <li className="list-inline-item badge badge-danger">
                     {i18n.t('banned')}
@@ -455,8 +459,9 @@ export class User extends Component<any, UserState> {
             ) : (
               <>
                 <a
-                  className={`btn btn-block btn-secondary mt-3 ${!this.state
-                    .user.matrix_user_id && 'disabled'}`}
+                  className={`btn btn-block btn-secondary mt-3 ${
+                    !this.state.user.matrix_user_id && 'disabled'
+                  }`}
                   target="_blank"
                   href={`https://matrix.to/#/${this.state.user.matrix_user_id}`}
                 >
index 5003986b51a83e29a9aa5e2d6c24fd60cdbe0a08..a57b93498fcd533993f025b9c654735ef5795456 100644 (file)
@@ -1,6 +1,6 @@
 const host = `${window.location.hostname}`;
 const port = `${
-  window.location.port == '4444' ? '8536' : window.location.port
+  window.location.port == '4444' ? '8540' : window.location.port
 }`;
 const endpoint = `${host}:${port}`;