Radish alpha
r
rad:z4D5UCArafTzTQpDZNQRuqswh3ury
Radicle desktop app
Radicle
Git
Persist tab scroll positions in patch view
Archived rudolfs opened 1 year ago
3 files changed +77 -13 2a7c705e 8c6ce467
modified src/components/Border.svelte
@@ -52,6 +52,22 @@
      `--local-button-color-1: var(--color-fill-${variant});` +
      `--local-hover-background-color: ${hoverable ? "var(--color-background-float)" : styleBackgroundColor}`,
  );
+

+
  let contentContainer: HTMLElement | undefined = $state();
+

+
  export function setScrollPosition(position: number) {
+
    if (contentContainer) {
+
      contentContainer.scrollTop = position;
+
    }
+
  }
+

+
  export function getScrollPosition() {
+
    if (contentContainer) {
+
      return contentContainer.scrollTop;
+
    } else {
+
      return 0;
+
    }
+
  }
</script>

<style>
@@ -244,6 +260,7 @@
  <div class="p3-1"></div>
  <div class="p3-2"></div>
  <div
+
    bind:this={contentContainer}
    class="p3-3"
    style:min-width={styleMinWidth}
    style:display={styleDisplay}
modified src/components/File.svelte
@@ -33,7 +33,7 @@

  .sticky {
    position: sticky;
-
    top: 0;
+
    top: -1rem;
  }

  .left {
modified src/views/repo/Patch.svelte
@@ -42,6 +42,7 @@
  import Sidebar from "@app/components/Sidebar.svelte";
  import Tab from "@app/components/Tab.svelte";
  import TextInput from "@app/components/TextInput.svelte";
+
  import { tick } from "svelte";

  interface Props {
    repo: RepoInfo;
@@ -77,6 +78,33 @@
  let assigneesSaveInProgress: boolean = $state(false);
  let tab: "patch" | "revisions" | "timeline" = $state("patch");
  let selectedRevision: Revision = $state(revisions.slice(-1)[0]);
+
  let container: Border;
+

+
  let patchTabScrollPosition: number = 0;
+
  let revisionsTabScrollPosition: number = 0;
+
  let timelineTabScrollPosition: number = 0;
+

+
  async function withPersistScrollPosition(callback: () => void) {
+
    if (tab === "patch") {
+
      patchTabScrollPosition = container.getScrollPosition();
+
    } else if (tab === "revisions") {
+
      revisionsTabScrollPosition = container.getScrollPosition();
+
    } else if (tab === "timeline") {
+
      timelineTabScrollPosition = container.getScrollPosition();
+
    }
+

+
    callback();
+

+
    await tick();
+

+
    if (tab === "patch") {
+
      container.setScrollPosition(patchTabScrollPosition);
+
    } else if (tab === "revisions") {
+
      container.setScrollPosition(revisionsTabScrollPosition);
+
    } else if (tab === "timeline") {
+
      container.setScrollPosition(timelineTabScrollPosition);
+
    }
+
  }

  $effect(() => {
    patchTeasers = patches.content;
@@ -540,8 +568,10 @@
          </span>
          <Tab
            active={tab === "patch"}
-
            onclick={() => {
-
              tab = "patch";
+
            onclick={async () => {
+
              await withPersistScrollPosition(() => {
+
                tab = "patch";
+
              });
            }}>
            {formatOid(patch.id)}
            <span
@@ -554,8 +584,10 @@
          {#if revisions.length > 1}
            <Tab
              active={tab === "revisions"}
-
              onclick={() => {
-
                tab = "revisions";
+
              onclick={async () => {
+
                await withPersistScrollPosition(() => {
+
                  tab = "revisions";
+
                });
              }}>
              {formatOid(selectedRevision.id)}
              <RevisionBadges revision={selectedRevision} {revisions} />
@@ -565,17 +597,22 @@
              {patch}
              {revisions}
              {selectedRevision}
-
              selectRevision={rev => {
+
              selectRevision={async rev => {
                selectedRevision = rev;
-
                tab = "revisions";
+

+
                await withPersistScrollPosition(() => {
+
                  tab = "revisions";
+
                });
              }} />
          {/if}

          <div style:margin-left="auto">
            <Tab
              active={tab === "timeline"}
-
              onclick={() => {
-
                tab = "timeline";
+
              onclick={async () => {
+
                await withPersistScrollPosition(() => {
+
                  tab = "timeline";
+
                });
              }}>
              <Icon name="clock" />
              Timeline
@@ -586,15 +623,18 @@
    </div>

    <Border
+
      bind:this={container}
      variant="ghost"
      flatTop
      styleWidth="100%"
      stylePadding="1rem"
+
      styleOverflow="scroll"
+
      styleHeight="calc(100vh - 16.5rem)"
      styleMinWidth="0"
      styleDisplay="block"
      styleFlexDirection="column"
      styleAlignItems="flex-start">
-
      {#if tab === "patch"}
+
      <div style:display={tab === "patch" ? undefined : "none"}>
        <RevisionComponent
          rid={repo.rid}
          repoDelegates={repo.delegates}
@@ -602,9 +642,16 @@
          {reload}
          revision={revisions[0]}
          {config} />
-
      {:else if tab === "timeline"}
+
      </div>
+

+
      <div style:display={tab === "timeline" ? undefined : "none"}>
        <PatchTimeline {activity} patchId={patch.id} />
-
      {:else}
+
      </div>
+

+
      <div
+
        style:display={tab !== "timeline" && tab !== "patch"
+
          ? undefined
+
          : "none"}>
        <RevisionComponent
          rid={repo.rid}
          repoDelegates={repo.delegates}
@@ -612,7 +659,7 @@
          {reload}
          revision={selectedRevision}
          {config} />
-
      {/if}
+
      </div>
    </Border>
  </div>
</Layout>