composing toots #21
					 2 changed files with 23 additions and 21 deletions
				
			
		| 
						 | 
					@ -1,4 +1,5 @@
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
 | 
					  batch,
 | 
				
			||||||
  createSignal,
 | 
					  createSignal,
 | 
				
			||||||
  createUniqueId,
 | 
					  createUniqueId,
 | 
				
			||||||
  onMount,
 | 
					  onMount,
 | 
				
			||||||
| 
						 | 
					@ -57,14 +58,12 @@ const TootVisibilityPickerDialog: Component<{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const discoverable = () => {
 | 
					  const discoverable = () => {
 | 
				
			||||||
    return props.visibility === "public";
 | 
					    return props.visibility === "public";
 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  const setDiscoverable = (setter: (v: boolean) => boolean) => {
 | 
					 | 
				
			||||||
    const nval = setter(discoverable())
 | 
					 | 
				
			||||||
    props.onVisibilityChange(nval ? "public" : "unlisted"); // trigger change
 | 
					 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const setDiscoverable = (setter: (v: boolean) => boolean) => {
 | 
				
			||||||
 | 
					    const nval = setter(discoverable());
 | 
				
			||||||
 | 
					    props.onVisibilityChange(nval ? "public" : "unlisted"); // trigger change
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <BottomSheet open={props.open} onClose={props.onClose} bottomUp>
 | 
					    <BottomSheet open={props.open} onClose={props.onClose} bottomUp>
 | 
				
			||||||
| 
						 | 
					@ -83,7 +82,7 @@ const TootVisibilityPickerDialog: Component<{
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      >
 | 
					      >
 | 
				
			||||||
        <List>
 | 
					        <List dense>
 | 
				
			||||||
          <ListItemButton onClick={[setKind, "public"]}>
 | 
					          <ListItemButton onClick={[setKind, "public"]}>
 | 
				
			||||||
            <ListItemIcon>
 | 
					            <ListItemIcon>
 | 
				
			||||||
              <PublicIcon />
 | 
					              <PublicIcon />
 | 
				
			||||||
| 
						 | 
					@ -155,27 +154,29 @@ const TootVisibilityPickerDialog: Component<{
 | 
				
			||||||
const ReplyEditor: Component<{
 | 
					const ReplyEditor: Component<{
 | 
				
			||||||
  profile: Account;
 | 
					  profile: Account;
 | 
				
			||||||
  replyToDisplayName: string;
 | 
					  replyToDisplayName: string;
 | 
				
			||||||
 | 
					  isTyping?: boolean
 | 
				
			||||||
 | 
					  onTypingChange: (value: boolean) => void
 | 
				
			||||||
}> = (props) => {
 | 
					}> = (props) => {
 | 
				
			||||||
  let inputRef: HTMLTextAreaElement;
 | 
					  let inputRef: HTMLTextAreaElement;
 | 
				
			||||||
  const buttonId = createUniqueId();
 | 
					  const buttonId = createUniqueId();
 | 
				
			||||||
  const menuId = createUniqueId();
 | 
					  const menuId = createUniqueId();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const [typing, setTyping] = createSignal(false);
 | 
					  const typing = () => props.isTyping
 | 
				
			||||||
 | 
					  const setTyping = (v: boolean) => props.onTypingChange(v)
 | 
				
			||||||
  const [visibility, setVisibility] = createSignal<TootVisibility>("public");
 | 
					  const [visibility, setVisibility] = createSignal<TootVisibility>("public");
 | 
				
			||||||
  const [permPicker, setPermPicker] = createSignal(false);
 | 
					  const [permPicker, setPermPicker] = createSignal(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  onMount(() => {
 | 
					  onMount(() => {
 | 
				
			||||||
    makeEventListener(inputRef, "focus", () => setTyping(true));
 | 
					    makeEventListener(inputRef, "focus", () => setTyping(true));
 | 
				
			||||||
    makeEventListener(inputRef, "blur", () => setTyping(false));
 | 
					 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const containerStyle = () =>
 | 
					  const containerStyle = () =>
 | 
				
			||||||
    typing()
 | 
					    typing() || permPicker()
 | 
				
			||||||
      ? {
 | 
					      ? {
 | 
				
			||||||
          position: "sticky" as const,
 | 
					          position: "sticky" as const,
 | 
				
			||||||
          top: "var(--scaffold-topbar-height, 0)",
 | 
					          top: "var(--scaffold-topbar-height, 0)",
 | 
				
			||||||
          bottom: "var(--safe-area-inset-bottom, 0)",
 | 
					          bottom: "var(--safe-area-inset-bottom, 0)",
 | 
				
			||||||
          "z-index": 1,
 | 
					          "z-index": 2,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      : undefined;
 | 
					      : undefined;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -196,7 +197,7 @@ const ReplyEditor: Component<{
 | 
				
			||||||
    <div
 | 
					    <div
 | 
				
			||||||
      class={tootComposers.composer}
 | 
					      class={tootComposers.composer}
 | 
				
			||||||
      style={containerStyle()}
 | 
					      style={containerStyle()}
 | 
				
			||||||
      onClick={() => setTyping(true)}
 | 
					      onClick={(e) => inputRef.focus()}
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      <div class={tootComposers.replyInput}>
 | 
					      <div class={tootComposers.replyInput}>
 | 
				
			||||||
        <Avatar src={props.profile.inf?.avatar} />
 | 
					        <Avatar src={props.profile.inf?.avatar} />
 | 
				
			||||||
| 
						 | 
					@ -219,7 +220,7 @@ const ReplyEditor: Component<{
 | 
				
			||||||
      >
 | 
					      >
 | 
				
			||||||
        <Button onClick={[setPermPicker, true]} id={buttonId}>
 | 
					        <Button onClick={[setPermPicker, true]} id={buttonId}>
 | 
				
			||||||
          {visibilityText()}
 | 
					          {visibilityText()}
 | 
				
			||||||
          <ArrowDropDown />
 | 
					          <ArrowDropDown sx={{ marginTop: "-0.25em" }} />
 | 
				
			||||||
        </Button>
 | 
					        </Button>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,17 +3,13 @@ import {
 | 
				
			||||||
  createEffect,
 | 
					  createEffect,
 | 
				
			||||||
  createRenderEffect,
 | 
					  createRenderEffect,
 | 
				
			||||||
  createResource,
 | 
					  createResource,
 | 
				
			||||||
 | 
					  createSignal,
 | 
				
			||||||
  For,
 | 
					  For,
 | 
				
			||||||
  Show,
 | 
					  Show,
 | 
				
			||||||
  type Component,
 | 
					  type Component,
 | 
				
			||||||
} from "solid-js";
 | 
					} from "solid-js";
 | 
				
			||||||
import Scaffold from "../material/Scaffold";
 | 
					import Scaffold from "../material/Scaffold";
 | 
				
			||||||
import {
 | 
					import { AppBar, CircularProgress, IconButton, Toolbar } from "@suid/material";
 | 
				
			||||||
  AppBar,
 | 
					 | 
				
			||||||
  CircularProgress,
 | 
					 | 
				
			||||||
  IconButton,
 | 
					 | 
				
			||||||
  Toolbar,
 | 
					 | 
				
			||||||
} from "@suid/material";
 | 
					 | 
				
			||||||
import { Title } from "../material/typography";
 | 
					import { Title } from "../material/typography";
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  ArrowBack as BackIcon,
 | 
					  ArrowBack as BackIcon,
 | 
				
			||||||
| 
						 | 
					@ -41,14 +37,13 @@ function getCache(acct: string, id: string) {
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const TootBottomSheet: Component = (props) => {
 | 
					const TootBottomSheet: Component = (props) => {
 | 
				
			||||||
  const params = useParams<{ acct: string; id: string }>();
 | 
					  const params = useParams<{ acct: string; id: string }>();
 | 
				
			||||||
  const location = useLocation<{ tootBottomSheetPushedCount?: number }>();
 | 
					  const location = useLocation<{ tootBottomSheetPushedCount?: number }>();
 | 
				
			||||||
  const navigate = useNavigate();
 | 
					  const navigate = useNavigate();
 | 
				
			||||||
  const allSession = useSessions();
 | 
					  const allSession = useSessions();
 | 
				
			||||||
  const time = createTimeSource();
 | 
					  const time = createTimeSource();
 | 
				
			||||||
 | 
					  const [isInTyping, setInTyping] = createSignal(false);
 | 
				
			||||||
  const acctText = () => decodeURIComponent(params.acct);
 | 
					  const acctText = () => decodeURIComponent(params.acct);
 | 
				
			||||||
  const session = () => {
 | 
					  const session = () => {
 | 
				
			||||||
    const [inputUsername, inputSite] = acctText().split("@", 2);
 | 
					    const [inputUsername, inputSite] = acctText().split("@", 2);
 | 
				
			||||||
| 
						 | 
					@ -164,6 +159,10 @@ const TootBottomSheet: Component = (props) => {
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const switchContext = (status: mastodon.v1.Status) => {
 | 
					  const switchContext = (status: mastodon.v1.Status) => {
 | 
				
			||||||
 | 
					    if (isInTyping()) {
 | 
				
			||||||
 | 
					      setInTyping(false);
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    setCache(params.acct, status);
 | 
					    setCache(params.acct, status);
 | 
				
			||||||
    navigate(`/${params.acct}/${status.id}`, {
 | 
					    navigate(`/${params.acct}/${status.id}`, {
 | 
				
			||||||
      state: {
 | 
					      state: {
 | 
				
			||||||
| 
						 | 
					@ -240,6 +239,8 @@ const TootBottomSheet: Component = (props) => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <Show when={profile()}>
 | 
					        <Show when={profile()}>
 | 
				
			||||||
          <ReplyEditor
 | 
					          <ReplyEditor
 | 
				
			||||||
 | 
					            isTyping={isInTyping()}
 | 
				
			||||||
 | 
					            onTypingChange={setInTyping}
 | 
				
			||||||
            profile={profile()!}
 | 
					            profile={profile()!}
 | 
				
			||||||
            replyToDisplayName={toot()?.account?.displayName || ""}
 | 
					            replyToDisplayName={toot()?.account?.displayName || ""}
 | 
				
			||||||
          />
 | 
					          />
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue