Profile: add subscribe menu
This commit is contained in:
		
							parent
							
								
									8a435be4c8
								
							
						
					
					
						commit
						65fa4c4fa5
					
				
					 6 changed files with 226 additions and 151 deletions
				
			
		| 
						 | 
				
			
			@ -3,8 +3,9 @@ import { MenuList } from "@suid/material";
 | 
			
		|||
import {
 | 
			
		||||
  createEffect,
 | 
			
		||||
  createSignal,
 | 
			
		||||
  type Component,
 | 
			
		||||
  type JSX,
 | 
			
		||||
  type ParentComponent,
 | 
			
		||||
  type ParentProps,
 | 
			
		||||
} from "solid-js";
 | 
			
		||||
import { ANIM_CURVE_STD } from "./theme";
 | 
			
		||||
import "./Menu.css";
 | 
			
		||||
| 
						 | 
				
			
			@ -13,13 +14,13 @@ import {
 | 
			
		|||
  animateShrinkToTopRight,
 | 
			
		||||
} from "../platform/anim";
 | 
			
		||||
 | 
			
		||||
type Anchor = Pick<DOMRect, "top" | "left" | "right">
 | 
			
		||||
export type Anchor = Pick<DOMRect, "top" | "left" | "right">
 | 
			
		||||
 | 
			
		||||
type Props = {
 | 
			
		||||
export type MenuProps = ParentProps<{
 | 
			
		||||
  open?: boolean;
 | 
			
		||||
  onClose?: JSX.EventHandlerUnion<HTMLDialogElement, Event>;
 | 
			
		||||
  anchor: () => Anchor;
 | 
			
		||||
};
 | 
			
		||||
}>;
 | 
			
		||||
 | 
			
		||||
function px(n?: number) {
 | 
			
		||||
  if (n) {
 | 
			
		||||
| 
						 | 
				
			
			@ -29,7 +30,22 @@ function px(n?: number) {
 | 
			
		|||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const Menu: ParentComponent<Props> = (props) => {
 | 
			
		||||
export function createManagedMenuState() {
 | 
			
		||||
  const [anchor, setAnchor] = createSignal<Anchor>();
 | 
			
		||||
 | 
			
		||||
  return [
 | 
			
		||||
    setAnchor,
 | 
			
		||||
    {
 | 
			
		||||
      get open() {
 | 
			
		||||
        return !!anchor();
 | 
			
		||||
      },
 | 
			
		||||
      anchor: anchor as () => Anchor,
 | 
			
		||||
      onClose: () => setAnchor(),
 | 
			
		||||
    },
 | 
			
		||||
  ] as const;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const Menu: Component<MenuProps> = (props) => {
 | 
			
		||||
  let root: HTMLDialogElement;
 | 
			
		||||
  const windowSize = useWindowSize();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										22
									
								
								src/material/Scaffold.css
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/material/Scaffold.css
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,22 @@
 | 
			
		|||
 | 
			
		||||
.Scaffold__topbar {
 | 
			
		||||
  position: sticky;
 | 
			
		||||
  top: 0px;
 | 
			
		||||
  z-index: var(--tutu-zidx-nav, auto);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.Scaffold__fab-dock {
 | 
			
		||||
  position: fixed;
 | 
			
		||||
  bottom: 40px;
 | 
			
		||||
  right: 40px;
 | 
			
		||||
  z-index: var(--tutu-zidx-nav, auto);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.Scaffold__bottom-dock {
 | 
			
		||||
  position: sticky;
 | 
			
		||||
  bottom: 0;
 | 
			
		||||
  left: 0;
 | 
			
		||||
  right: 0;
 | 
			
		||||
  z-index: var(--tutu-zidx-nav, auto);
 | 
			
		||||
  padding-bottom: var(--safe-area-inset-bottom, 0);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,66 +1,67 @@
 | 
			
		|||
import { createElementSize } from "@solid-primitives/resize-observer";
 | 
			
		||||
import {
 | 
			
		||||
  JSX,
 | 
			
		||||
  Show,
 | 
			
		||||
  createRenderEffect,
 | 
			
		||||
  createSignal,
 | 
			
		||||
  onCleanup,
 | 
			
		||||
  type JSX,
 | 
			
		||||
  type ParentComponent,
 | 
			
		||||
  splitProps,
 | 
			
		||||
  type Component,
 | 
			
		||||
  type ParentProps,
 | 
			
		||||
} from "solid-js";
 | 
			
		||||
import { css } from "solid-styled";
 | 
			
		||||
import "./Scaffold.css";
 | 
			
		||||
 | 
			
		||||
interface ScaffoldProps {
 | 
			
		||||
  topbar?: JSX.Element;
 | 
			
		||||
  fab?: JSX.Element;
 | 
			
		||||
  bottom?: JSX.Element;
 | 
			
		||||
}
 | 
			
		||||
type ScaffoldProps = ParentProps<
 | 
			
		||||
  {
 | 
			
		||||
    topbar?: JSX.Element;
 | 
			
		||||
    fab?: JSX.Element;
 | 
			
		||||
    bottom?: JSX.Element;
 | 
			
		||||
  } & JSX.HTMLElementTags["div"]
 | 
			
		||||
>;
 | 
			
		||||
 | 
			
		||||
const Scaffold: ParentComponent<ScaffoldProps> = (props) => {
 | 
			
		||||
/**
 | 
			
		||||
 * The passthrough props are passed to the content container.
 | 
			
		||||
 */
 | 
			
		||||
const Scaffold: Component<ScaffoldProps> = (props) => {
 | 
			
		||||
  const [managed, rest] = splitProps(props, [
 | 
			
		||||
    "topbar",
 | 
			
		||||
    "fab",
 | 
			
		||||
    "bottom",
 | 
			
		||||
    "children",
 | 
			
		||||
    "ref",
 | 
			
		||||
  ]);
 | 
			
		||||
  const [topbarElement, setTopbarElement] = createSignal<HTMLElement>();
 | 
			
		||||
 | 
			
		||||
  const topbarSize = createElementSize(topbarElement);
 | 
			
		||||
 | 
			
		||||
  css`
 | 
			
		||||
    .scaffold-content {
 | 
			
		||||
      --scaffold-topbar-height: ${(topbarSize.height?.toString() ?? 0) + "px"};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .topbar {
 | 
			
		||||
      position: sticky;
 | 
			
		||||
      top: 0px;
 | 
			
		||||
      z-index: var(--tutu-zidx-nav, auto);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .fab-dock {
 | 
			
		||||
      position: fixed;
 | 
			
		||||
      bottom: 40px;
 | 
			
		||||
      right: 40px;
 | 
			
		||||
      z-index: var(--tutu-zidx-nav, auto);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .bottom-dock {
 | 
			
		||||
      position: sticky;
 | 
			
		||||
      bottom: 0;
 | 
			
		||||
      left: 0;
 | 
			
		||||
      right: 0;
 | 
			
		||||
      z-index: var(--tutu-zidx-nav, auto);
 | 
			
		||||
      padding-bottom: var(--safe-area-inset-bottom, 0);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
  `;
 | 
			
		||||
  return (
 | 
			
		||||
    <>
 | 
			
		||||
      <Show when={props.topbar}>
 | 
			
		||||
        <div class="topbar" ref={setTopbarElement}>
 | 
			
		||||
        <div class="Scaffold__topbar" ref={setTopbarElement}>
 | 
			
		||||
          {props.topbar}
 | 
			
		||||
        </div>
 | 
			
		||||
      </Show>
 | 
			
		||||
      <Show when={props.fab}>
 | 
			
		||||
        <div class="fab-dock">{props.fab}</div>
 | 
			
		||||
        <div class="Scaffold__fab-dock">{props.fab}</div>
 | 
			
		||||
      </Show>
 | 
			
		||||
      <div class="scaffold-content">{props.children}</div>
 | 
			
		||||
      <div
 | 
			
		||||
        ref={(e) => {
 | 
			
		||||
          createRenderEffect(() => {
 | 
			
		||||
            e.style.setProperty(
 | 
			
		||||
              "--scaffold-topbar-height",
 | 
			
		||||
              (topbarSize.height?.toString() ?? 0) + "px",
 | 
			
		||||
            );
 | 
			
		||||
          });
 | 
			
		||||
 | 
			
		||||
          if (managed.ref) {
 | 
			
		||||
            (managed.ref as (val: typeof e) => void)(e);
 | 
			
		||||
          }
 | 
			
		||||
        }}
 | 
			
		||||
        {...rest}
 | 
			
		||||
      >
 | 
			
		||||
        {managed.children}
 | 
			
		||||
      </div>
 | 
			
		||||
      <Show when={props.bottom}>
 | 
			
		||||
        <div class="bottom-dock">{props.bottom}</div>
 | 
			
		||||
        <div class="Scaffold__bottom-dock">{props.bottom}</div>
 | 
			
		||||
      </Show>
 | 
			
		||||
    </>
 | 
			
		||||
  );
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -106,6 +106,8 @@
 | 
			
		|||
 | 
			
		||||
  /* Submenu (+1dp for each submenu) */
 | 
			
		||||
  --tutu-shadow-e9: 0px 9px 18px 0px var(--tutu-color-shadow);
 | 
			
		||||
  --tutu-shadow-e10: 0px 10px 18px 0px var(--tutu-color-shadow);
 | 
			
		||||
  --tutu-shadow-e11: 0px 11px 18px 0px var(--tutu-color-shadow-l1);
 | 
			
		||||
 | 
			
		||||
  /* (pressed) FAB */
 | 
			
		||||
  --tutu-shadow-e12: 0px 12px 24px 0px var(--tutu-color-shadow-l1);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										82
									
								
								src/profiles/Profile.css
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								src/profiles/Profile.css
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,82 @@
 | 
			
		|||
.Profile {
 | 
			
		||||
  .intro {
 | 
			
		||||
    background-color: var(--tutu-color-surface-d);
 | 
			
		||||
    color: var(--tutu-color-on-surface);
 | 
			
		||||
    padding: 16px 12px;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-flow: column nowrap;
 | 
			
		||||
    gap: 16px;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .description {
 | 
			
		||||
    & a {
 | 
			
		||||
      color: inherit;
 | 
			
		||||
      font-style: italic;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    word-break: break-all;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .acct-grp {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-flow: row wrap;
 | 
			
		||||
    gap: 16px;
 | 
			
		||||
    align-items: center;
 | 
			
		||||
 | 
			
		||||
    & > :nth-child(2) {
 | 
			
		||||
      flex-grow: 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    & > :last-child {
 | 
			
		||||
      flex-grow: 1;
 | 
			
		||||
      text-align: right;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .name-grp {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-flow: column nowrap;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  table.acct-fields {
 | 
			
		||||
    word-break: break-all;
 | 
			
		||||
 | 
			
		||||
    & td > a {
 | 
			
		||||
      display: inline-flex;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
      color: inherit;
 | 
			
		||||
      min-height: 44px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    & a > .invisible {
 | 
			
		||||
      display: none;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    & svg {
 | 
			
		||||
      vertical-align: middle;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .toot-list-toolbar {
 | 
			
		||||
    position: sticky;
 | 
			
		||||
    top: var(--scaffold-topbar-height);
 | 
			
		||||
    z-index: calc(var(--tutu-zidx-nav, 1) - 1);
 | 
			
		||||
    background: var(--tutu-color-surface);
 | 
			
		||||
    border-bottom: 1px solid var(--tutu-color-surface-d);
 | 
			
		||||
    contain: content;
 | 
			
		||||
    /* TODO: box-shadow is needed here (same as app bar, e6).
 | 
			
		||||
    There is no good way to detect if the sticky is "sticked" -
 | 
			
		||||
    so let's leave it for future.
 | 
			
		||||
 | 
			
		||||
    For now we use a trick to make it looks better.
 | 
			
		||||
    */
 | 
			
		||||
    box-shadow: 0px -2px 4px 0px var(--tutu-color-shadow);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.Profile__page-title {
 | 
			
		||||
  flex-grow: 1;
 | 
			
		||||
  white-space: nowrap;
 | 
			
		||||
  overflow: hidden;
 | 
			
		||||
  text-overflow: ellipsis;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -5,6 +5,8 @@ import {
 | 
			
		|||
  createSignal,
 | 
			
		||||
  createUniqueId,
 | 
			
		||||
  For,
 | 
			
		||||
  Switch,
 | 
			
		||||
  Match,
 | 
			
		||||
  onCleanup,
 | 
			
		||||
  Show,
 | 
			
		||||
  type Component,
 | 
			
		||||
| 
						 | 
				
			
			@ -42,13 +44,13 @@ import { useSessionForAcctStr } from "../masto/clients";
 | 
			
		|||
import { resolveCustomEmoji } from "../masto/toot";
 | 
			
		||||
import { FastAverageColor } from "fast-average-color";
 | 
			
		||||
import { useWindowSize } from "@solid-primitives/resize-observer";
 | 
			
		||||
import { css } from "solid-styled";
 | 
			
		||||
import { createTimeline, createTimelineSnapshot } from "../masto/timelines";
 | 
			
		||||
import TootList from "../timelines/TootList";
 | 
			
		||||
import { createTimeSource, TimeSourceProvider } from "../platform/timesrc";
 | 
			
		||||
import TootFilterButton from "./TootFilterButton";
 | 
			
		||||
import Menu from "../material/Menu";
 | 
			
		||||
import Menu, { createManagedMenuState } from "../material/Menu";
 | 
			
		||||
import { share } from "../platform/share";
 | 
			
		||||
import "./Profile.css";
 | 
			
		||||
 | 
			
		||||
const Profile: Component = () => {
 | 
			
		||||
  const navigate = useNavigate();
 | 
			
		||||
| 
						 | 
				
			
			@ -65,6 +67,10 @@ const Profile: Component = () => {
 | 
			
		|||
  const menuButId = createUniqueId();
 | 
			
		||||
 | 
			
		||||
  const [menuOpen, setMenuOpen] = createSignal(false);
 | 
			
		||||
  const [subscribeMenuOpen, setSubscribeMenuOpen] = createSignal(false);
 | 
			
		||||
  let subcribeMenuAnchor: { top: number; right: number; left: number };
 | 
			
		||||
 | 
			
		||||
  const [openSubscribeMenu, subscribeMenuState] = createManagedMenuState();
 | 
			
		||||
 | 
			
		||||
  const [scrolledPastBanner, setScrolledPastBanner] = createSignal(false);
 | 
			
		||||
  const obx = new IntersectionObserver(
 | 
			
		||||
| 
						 | 
				
			
			@ -132,89 +138,6 @@ const Profile: Component = () => {
 | 
			
		|||
    recentTootChunk.loading ||
 | 
			
		||||
    (recentTootFilter().pinned && pinnedTootChunk.loading);
 | 
			
		||||
 | 
			
		||||
  css`
 | 
			
		||||
    .intro {
 | 
			
		||||
      background-color: var(--tutu-color-surface-d);
 | 
			
		||||
      color: var(--tutu-color-on-surface);
 | 
			
		||||
      padding: 16px 12px;
 | 
			
		||||
      display: flex;
 | 
			
		||||
      flex-flow: column nowrap;
 | 
			
		||||
      gap: 16px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .description {
 | 
			
		||||
      & :global(a) {
 | 
			
		||||
        color: inherit;
 | 
			
		||||
        font-style: italic;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      word-break: break-all;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .acct-grp {
 | 
			
		||||
      display: flex;
 | 
			
		||||
      flex-flow: row wrap;
 | 
			
		||||
      gap: 16px;
 | 
			
		||||
      align-items: center;
 | 
			
		||||
 | 
			
		||||
      & > :nth-child(2) {
 | 
			
		||||
        flex-grow: 1;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      & > :last-child {
 | 
			
		||||
        flex-grow: 1;
 | 
			
		||||
        text-align: right;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .name-grp {
 | 
			
		||||
      display: flex;
 | 
			
		||||
      flex-flow: column nowrap;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    table.acct-fields {
 | 
			
		||||
      word-break: break-all;
 | 
			
		||||
 | 
			
		||||
      & td > :global(a) {
 | 
			
		||||
        display: inline-flex;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        color: inherit;
 | 
			
		||||
        min-height: 44px;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      & :global(a > .invisible) {
 | 
			
		||||
        display: none;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      & :global(svg) {
 | 
			
		||||
        vertical-align: middle;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .page-title {
 | 
			
		||||
      flex-grow: 1;
 | 
			
		||||
      white-space: nowrap;
 | 
			
		||||
      overflow: hidden;
 | 
			
		||||
      text-overflow: ellipsis;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .toot-list-toolbar {
 | 
			
		||||
      position: sticky;
 | 
			
		||||
      top: var(--scaffold-topbar-height);
 | 
			
		||||
      z-index: calc(var(--tutu-zidx-nav, 1) - 1);
 | 
			
		||||
      background: var(--tutu-color-surface);
 | 
			
		||||
      border-bottom: 1px solid var(--tutu-color-surface-d);
 | 
			
		||||
      contain: content;
 | 
			
		||||
      /* TODO: box-shadow is needed here (same as app bar, e6).
 | 
			
		||||
      There is no good way to detect if the sticky is "sticked" -
 | 
			
		||||
      so let's leave it for future.
 | 
			
		||||
 | 
			
		||||
      For now we use a trick to make it looks better.
 | 
			
		||||
      */
 | 
			
		||||
      box-shadow: 0px -2px 4px 0px var(--tutu-color-shadow);
 | 
			
		||||
    }
 | 
			
		||||
  `;
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <Scaffold
 | 
			
		||||
      topbar={
 | 
			
		||||
| 
						 | 
				
			
			@ -241,8 +164,7 @@ const Profile: Component = () => {
 | 
			
		|||
              <Close />
 | 
			
		||||
            </IconButton>
 | 
			
		||||
            <Title
 | 
			
		||||
              use:solid-styled
 | 
			
		||||
              class="page-title"
 | 
			
		||||
              class="Profile__page-title"
 | 
			
		||||
              style={{
 | 
			
		||||
                visibility: scrolledPastBanner() ? undefined : "hidden",
 | 
			
		||||
              }}
 | 
			
		||||
| 
						 | 
				
			
			@ -261,6 +183,7 @@ const Profile: Component = () => {
 | 
			
		|||
          </Toolbar>
 | 
			
		||||
        </AppBar>
 | 
			
		||||
      }
 | 
			
		||||
      class="Profile"
 | 
			
		||||
    >
 | 
			
		||||
      <Menu
 | 
			
		||||
        open={menuOpen()}
 | 
			
		||||
| 
						 | 
				
			
			@ -269,25 +192,27 @@ const Profile: Component = () => {
 | 
			
		|||
          document.getElementById(menuButId)!.getBoundingClientRect()
 | 
			
		||||
        }
 | 
			
		||||
      >
 | 
			
		||||
        <Show
 | 
			
		||||
          when={isCurrentSessionProfile()}
 | 
			
		||||
          fallback={
 | 
			
		||||
        <Show when={session().account}>
 | 
			
		||||
          <Show
 | 
			
		||||
            when={isCurrentSessionProfile()}
 | 
			
		||||
            fallback={
 | 
			
		||||
              <MenuItem disabled>
 | 
			
		||||
                <ListItemIcon>
 | 
			
		||||
                  <PlaylistAdd />
 | 
			
		||||
                </ListItemIcon>
 | 
			
		||||
                <ListItemText>Subscribe...</ListItemText>
 | 
			
		||||
              </MenuItem>
 | 
			
		||||
            }
 | 
			
		||||
          >
 | 
			
		||||
            <MenuItem disabled>
 | 
			
		||||
              <ListItemIcon>
 | 
			
		||||
                <PlaylistAdd />
 | 
			
		||||
                <Edit />
 | 
			
		||||
              </ListItemIcon>
 | 
			
		||||
              <ListItemText>Subscribe...</ListItemText>
 | 
			
		||||
              <ListItemText>Edit...</ListItemText>
 | 
			
		||||
            </MenuItem>
 | 
			
		||||
          }
 | 
			
		||||
        >
 | 
			
		||||
          <MenuItem disabled>
 | 
			
		||||
            <ListItemIcon>
 | 
			
		||||
              <Edit />
 | 
			
		||||
            </ListItemIcon>
 | 
			
		||||
            <ListItemText>Edit...</ListItemText>
 | 
			
		||||
          </MenuItem>
 | 
			
		||||
          </Show>
 | 
			
		||||
          <Divider />
 | 
			
		||||
        </Show>
 | 
			
		||||
        <Divider />
 | 
			
		||||
        <MenuItem disabled>
 | 
			
		||||
          <ListItemIcon>
 | 
			
		||||
            <Group />
 | 
			
		||||
| 
						 | 
				
			
			@ -360,6 +285,15 @@ const Profile: Component = () => {
 | 
			
		|||
        ></img>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <Menu {...subscribeMenuState}>
 | 
			
		||||
        <MenuItem disabled>
 | 
			
		||||
          <ListItemText>
 | 
			
		||||
            <span>{session().account?.inf?.displayName || ""}</span>
 | 
			
		||||
            <span>'s timeline</span>
 | 
			
		||||
          </ListItemText>
 | 
			
		||||
        </MenuItem>
 | 
			
		||||
      </Menu>
 | 
			
		||||
 | 
			
		||||
      <div
 | 
			
		||||
        class="intro"
 | 
			
		||||
        style={{
 | 
			
		||||
| 
						 | 
				
			
			@ -385,9 +319,27 @@ const Profile: Component = () => {
 | 
			
		|||
            <span>{fullUsername()}</span>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div>
 | 
			
		||||
            <Button variant="contained" color="secondary">
 | 
			
		||||
              Subscribe
 | 
			
		||||
            </Button>
 | 
			
		||||
            <Switch>
 | 
			
		||||
              <Match when={!session().account}>{<></>}</Match>
 | 
			
		||||
              <Match when={isCurrentSessionProfile()}>
 | 
			
		||||
                <IconButton color="inherit">
 | 
			
		||||
                  <Edit />
 | 
			
		||||
                </IconButton>
 | 
			
		||||
              </Match>
 | 
			
		||||
              <Match when={true}>
 | 
			
		||||
                <Button
 | 
			
		||||
                  variant="contained"
 | 
			
		||||
                  color="secondary"
 | 
			
		||||
                  onClick={(event) => {
 | 
			
		||||
                    openSubscribeMenu(
 | 
			
		||||
                      event.currentTarget.getBoundingClientRect(),
 | 
			
		||||
                    );
 | 
			
		||||
                  }}
 | 
			
		||||
                >
 | 
			
		||||
                  Subscribe
 | 
			
		||||
                </Button>
 | 
			
		||||
              </Match>
 | 
			
		||||
            </Switch>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue