]> Untitled Git - lemmy-ui.git/blobdiff - src/shared/components/app/navbar.tsx
Feature/user community block (#362)
[lemmy-ui.git] / src / shared / components / app / navbar.tsx
index 114ffb779dc6695a29682a3857ce4f2a34da0e0e..06304a8c53e45dee8f3ee21955e3e74fa342c628 100644 (file)
@@ -50,6 +50,7 @@ interface NavbarState {
   unreadCount: number;
   searchParam: string;
   toggleSearch: boolean;
+  showDropdown: boolean;
   onSiteBanner?(url: string): any;
 }
 
@@ -67,6 +68,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
     expanded: false,
     searchParam: "",
     toggleSearch: false,
+    showDropdown: false,
   };
   subscription: any;
 
@@ -122,15 +124,17 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
     }
   }
 
-  handleSearchParam(i: Navbar, event: any) {
-    i.state.searchParam = event.target.value;
-    i.setState(i.state);
+  componentWillUnmount() {
+    this.wsSub.unsubscribe();
+    this.userSub.unsubscribe();
+    this.unreadCountSub.unsubscribe();
   }
 
   updateUrl() {
     const searchParam = this.state.searchParam;
     this.setState({ searchParam: "" });
     this.setState({ toggleSearch: false });
+    this.setState({ showDropdown: false, expanded: false });
     if (searchParam === "") {
       this.context.router.history.push(`/search/`);
     } else {
@@ -141,54 +145,26 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
     }
   }
 
-  handleSearchSubmit(i: Navbar, event: any) {
-    event.preventDefault();
-    i.updateUrl();
-  }
-
-  handleSearchBtn(i: Navbar, event: any) {
-    event.preventDefault();
-    i.setState({ toggleSearch: true });
-
-    i.searchTextField.current.focus();
-    const offsetWidth = i.searchTextField.current.offsetWidth;
-    if (i.state.searchParam && offsetWidth > 100) {
-      i.updateUrl();
-    }
-  }
-
-  handleSearchBlur(i: Navbar, event: any) {
-    if (!(event.relatedTarget && event.relatedTarget.name !== "search-btn")) {
-      i.state.toggleSearch = false;
-      i.setState(i.state);
-    }
-  }
-
   render() {
     return this.navbar();
   }
 
-  componentWillUnmount() {
-    this.wsSub.unsubscribe();
-    this.userSub.unsubscribe();
-    this.unreadCountSub.unsubscribe();
-  }
-
   // TODO class active corresponding to current page
   navbar() {
-    let localUserView =
-      UserService.Instance.localUserView || this.props.site_res.my_user;
+    let myUserInfo =
+      UserService.Instance.myUserInfo || this.props.site_res.my_user;
+    let person = myUserInfo?.local_user_view.person;
     return (
       <nav class="navbar navbar-expand-lg navbar-light shadow-sm p-0 px-3">
         <div class="container">
           {this.props.site_res.site_view && (
-            <Link
+            <button
               title={
                 this.props.site_res.site_view.site.description ||
                 this.props.site_res.site_view.site.name
               }
-              className="d-flex align-items-center navbar-brand mr-md-3"
-              to="/"
+              className="d-flex align-items-center navbar-brand mr-md-3 btn btn-link"
+              onClick={linkEvent(this, this.handleGotoHome)}
             >
               {this.props.site_res.site_view.site.icon && showAvatars() && (
                 <PictrsImage
@@ -197,12 +173,12 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
                 />
               )}
               {this.props.site_res.site_view.site.name}
-            </Link>
+            </button>
           )}
           {this.state.isLoggedIn && (
-            <Link
-              className="ml-auto p-1 navbar-toggler nav-link border-0"
-              to="/inbox"
+            <button
+              className="ml-auto p-1 navbar-toggler nav-link border-0 btn btn-link"
+              onClick={linkEvent(this, this.handleGotoInbox)}
               title={i18n.t("inbox")}
             >
               <Icon icon="bell" />
@@ -216,7 +192,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
                   {this.state.unreadCount}
                 </span>
               )}
-            </Link>
+            </button>
           )}
           <button
             class="navbar-toggler border-0 p-1"
@@ -232,35 +208,32 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
           >
             <ul class="navbar-nav my-2 mr-auto">
               <li class="nav-item">
-                <Link
-                  className="nav-link"
-                  to="/communities"
+                <button
+                  className="nav-link btn btn-link"
+                  onClick={linkEvent(this, this.handleGotoCommunities)}
                   title={i18n.t("communities")}
                 >
                   {i18n.t("communities")}
-                </Link>
+                </button>
               </li>
               <li class="nav-item">
-                <Link
-                  className="nav-link"
-                  to={{
-                    pathname: "/create_post",
-                    state: { prevPath: this.currentLocation },
-                  }}
+                <button
+                  className="nav-link btn btn-link"
+                  onClick={linkEvent(this, this.handleGotoCreatePost)}
                   title={i18n.t("create_post")}
                 >
                   {i18n.t("create_post")}
-                </Link>
+                </button>
               </li>
               {this.canCreateCommunity && (
                 <li class="nav-item">
-                  <Link
-                    className="nav-link"
-                    to="/create_community"
+                  <button
+                    className="nav-link btn btn-link"
+                    onClick={linkEvent(this, this.handleGotoCreateCommunity)}
                     title={i18n.t("create_community")}
                   >
                     {i18n.t("create_community")}
-                  </Link>
+                  </button>
                 </li>
               )}
               <li class="nav-item">
@@ -276,13 +249,13 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
             <ul class="navbar-nav my-2">
               {this.canAdmin && (
                 <li className="nav-item">
-                  <Link
-                    className="nav-link"
-                    to={`/admin`}
+                  <button
+                    className="nav-link btn btn-link"
+                    onClick={linkEvent(this, this.handleGotoAdmin)}
                     title={i18n.t("admin_settings")}
                   >
                     <Icon icon="settings" />
-                  </Link>
+                  </button>
                 </li>
               )}
             </ul>
@@ -343,34 +316,73 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
                   </li>
                 </ul>
                 <ul class="navbar-nav">
-                  <li className="nav-item">
-                    <Link
-                      className="nav-link"
-                      to={`/u/${localUserView.person.name}`}
-                      title={i18n.t("settings")}
+                  <li class="nav-item dropdown">
+                    <button
+                      class="nav-link btn btn-link dropdown-toggle"
+                      onClick={linkEvent(this, this.handleShowDropdown)}
+                      id="navbarDropdown"
+                      role="button"
+                      aria-expanded="false"
                     >
                       <span>
-                        {localUserView.person.avatar && showAvatars() && (
-                          <PictrsImage src={localUserView.person.avatar} icon />
+                        {person.avatar && showAvatars() && (
+                          <PictrsImage src={person.avatar} icon />
                         )}
-                        {localUserView.person.display_name
-                          ? localUserView.person.display_name
-                          : localUserView.person.name}
+                        {person.display_name
+                          ? person.display_name
+                          : person.name}
                       </span>
-                    </Link>
+                    </button>
+                    {this.state.showDropdown && (
+                      <div class="dropdown-content">
+                        <li className="nav-item">
+                          <button
+                            className="nav-link btn btn-link"
+                            onClick={linkEvent(this, this.handleGotoProfile)}
+                            title={i18n.t("profile")}
+                          >
+                            <Icon icon="user" classes="mr-1" />
+                            {i18n.t("profile")}
+                          </button>
+                        </li>
+                        <li className="nav-item">
+                          <button
+                            className="nav-link btn btn-link"
+                            onClick={linkEvent(this, this.handleGotoSettings)}
+                            title={i18n.t("settings")}
+                          >
+                            <Icon icon="settings" classes="mr-1" />
+                            {i18n.t("settings")}
+                          </button>
+                        </li>
+                        <li>
+                          <hr class="dropdown-divider" />
+                        </li>
+                        <li className="nav-item">
+                          <button
+                            className="nav-link btn btn-link"
+                            onClick={linkEvent(this, this.handleLogoutClick)}
+                            title="test"
+                          >
+                            <Icon icon="log-out" classes="mr-1" />
+                            {i18n.t("logout")}
+                          </button>
+                        </li>
+                      </div>
+                    )}
                   </li>
                 </ul>
               </>
             ) : (
               <ul class="navbar-nav my-2">
                 <li className="ml-2 nav-item">
-                  <Link
+                  <button
                     className="btn btn-success"
-                    to="/login"
+                    onClick={linkEvent(this, this.handleGotoLogin)}
                     title={i18n.t("login_sign_up")}
                   >
                     {i18n.t("login_sign_up")}
-                  </Link>
+                  </button>
                 </li>
               </ul>
             )}
@@ -385,6 +397,95 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
     i.setState(i.state);
   }
 
+  handleSearchParam(i: Navbar, event: any) {
+    i.state.searchParam = event.target.value;
+    i.setState(i.state);
+  }
+
+  handleSearchSubmit(i: Navbar, event: any) {
+    event.preventDefault();
+    i.updateUrl();
+  }
+
+  handleSearchBtn(i: Navbar, event: any) {
+    event.preventDefault();
+    i.setState({ toggleSearch: true });
+
+    i.searchTextField.current.focus();
+    const offsetWidth = i.searchTextField.current.offsetWidth;
+    if (i.state.searchParam && offsetWidth > 100) {
+      i.updateUrl();
+    }
+  }
+
+  handleSearchBlur(i: Navbar, event: any) {
+    if (!(event.relatedTarget && event.relatedTarget.name !== "search-btn")) {
+      i.state.toggleSearch = false;
+      i.setState(i.state);
+    }
+  }
+
+  handleLogoutClick(i: Navbar) {
+    i.setState({ showDropdown: false, expanded: false });
+    UserService.Instance.logout();
+    i.context.router.history.push("/");
+    location.reload();
+  }
+
+  handleGotoSettings(i: Navbar) {
+    i.setState({ showDropdown: false, expanded: false });
+    i.context.router.history.push("/settings");
+  }
+
+  handleGotoProfile(i: Navbar) {
+    i.setState({ showDropdown: false, expanded: false });
+    i.context.router.history.push(
+      `/u/${UserService.Instance.myUserInfo.local_user_view.person.name}`
+    );
+  }
+
+  handleGotoCreatePost(i: Navbar) {
+    i.setState({ showDropdown: false, expanded: false });
+    i.context.router.history.push("/create_post", {
+      prevPath: i.currentLocation,
+    });
+  }
+
+  handleGotoCreateCommunity(i: Navbar) {
+    i.setState({ showDropdown: false, expanded: false });
+    i.context.router.history.push(`/create_community`);
+  }
+
+  handleGotoCommunities(i: Navbar) {
+    i.setState({ showDropdown: false, expanded: false });
+    i.context.router.history.push(`/communities`);
+  }
+
+  handleGotoHome(i: Navbar) {
+    i.setState({ showDropdown: false, expanded: false });
+    i.context.router.history.push(`/`);
+  }
+
+  handleGotoInbox(i: Navbar) {
+    i.setState({ showDropdown: false, expanded: false });
+    i.context.router.history.push(`/inbox`);
+  }
+
+  handleGotoAdmin(i: Navbar) {
+    i.setState({ showDropdown: false, expanded: false });
+    i.context.router.history.push(`/admin`);
+  }
+
+  handleGotoLogin(i: Navbar) {
+    i.setState({ showDropdown: false, expanded: false });
+    i.context.router.history.push(`/login`);
+  }
+
+  handleShowDropdown(i: Navbar) {
+    i.state.showDropdown = !i.state.showDropdown;
+    i.setState(i.state);
+  }
+
   parseMessage(msg: any) {
     let op = wsUserOp(msg);
     console.log(msg);
@@ -432,8 +533,10 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
       // This is only called on a successful login
       let data = wsJsonToRes<GetSiteResponse>(msg).data;
       console.log(data.my_user);
-      UserService.Instance.localUserView = data.my_user;
-      setTheme(UserService.Instance.localUserView.local_user.theme);
+      UserService.Instance.myUserInfo = data.my_user;
+      setTheme(
+        UserService.Instance.myUserInfo.local_user_view.local_user.theme
+      );
       i18n.changeLanguage(getLanguage());
       this.state.isLoggedIn = true;
       this.setState(this.state);
@@ -443,7 +546,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
       if (this.state.isLoggedIn) {
         if (
           data.recipient_ids.includes(
-            UserService.Instance.localUserView.local_user.id
+            UserService.Instance.myUserInfo.local_user_view.local_user.id
           )
         ) {
           this.state.replies.push(data.comment_view);
@@ -459,7 +562,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
       if (this.state.isLoggedIn) {
         if (
           data.private_message_view.recipient.id ==
-          UserService.Instance.localUserView.person.id
+          UserService.Instance.myUserInfo.local_user_view.person.id
         ) {
           this.state.messages.push(data.private_message_view);
           this.state.unreadCount++;
@@ -525,10 +628,10 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
 
   get canAdmin(): boolean {
     return (
-      UserService.Instance.localUserView &&
+      UserService.Instance.myUserInfo &&
       this.props.site_res.admins
         .map(a => a.person.id)
-        .includes(UserService.Instance.localUserView.person.id)
+        .includes(UserService.Instance.myUserInfo.local_user_view.person.id)
     );
   }
 
@@ -547,7 +650,7 @@ export class Navbar extends Component<NavbarProps, NavbarState> {
   }
 
   requestNotificationPermission() {
-    if (UserService.Instance.localUserView) {
+    if (UserService.Instance.myUserInfo) {
       document.addEventListener("DOMContentLoaded", function () {
         if (!Notification) {
           toast(i18n.t("notifications_error"), "danger");