···11-"use client";
22-33-import { useEffect, useRef } from "react";
44-import { mutate as swrMutate } from "swr";
55-import { useIdentityData } from "components/IdentityProvider";
66-import { addSelfAsDraftContributor } from "actions/publications/draftContributors";
77-88-// When a confirmed publication contributor opens a draft they're not yet
99-// tracked on, silently register them as a draft contributor so the draft
1010-// appears on their home dashboard. The server action is a no-op for
1111-// non-contributors and for the publication owner.
1212-export function AutoAddDraftContributorEffect(props: { leaflet_id: string }) {
1313- let { identity, mutate } = useIdentityData();
1414- let ran = useRef<string | null>(null);
1515-1616- useEffect(() => {
1717- if (!identity?.atp_did) return;
1818- if (ran.current === props.leaflet_id) return;
1919-2020- let alreadyTracked = (identity.contributor_leaflets ?? []).some(
2121- (row) => row.permission_tokens.id === props.leaflet_id,
2222- );
2323- let alreadyOwnedOnHome = identity.permission_token_on_homepage.some(
2424- (ptoh) => ptoh.permission_tokens.id === props.leaflet_id,
2525- );
2626- if (alreadyTracked || alreadyOwnedOnHome) return;
2727-2828- ran.current = props.leaflet_id;
2929- addSelfAsDraftContributor(props.leaflet_id).then((res) => {
3030- if (res.ok) {
3131- mutate();
3232- swrMutate("leaflets");
3333- }
3434- });
3535- }, [identity, props.leaflet_id, mutate]);
3636-3737- return null;
3838-}
-2
app/(app)/[leaflet_id]/Leaflet.tsx
···1414import { LeafletLayout } from "components/LeafletLayout";
1515import { WelcomeModal } from "./WelcomeModal";
1616import { AddToHomeEffect } from "./AddToHomeEffect";
1717-import { AutoAddDraftContributorEffect } from "./AutoAddDraftContributorEffect";
18171918export function Leaflet(props: {
2019 token: PermissionToken;
···4241 <UpdateLeafletTitle entityID={props.leaflet_id} />
4342 <WelcomeModal />
4443 <AddToHomeEffect />
4545- <AutoAddDraftContributorEffect leaflet_id={props.leaflet_id} />
4644 <SelectionManager />
4745 {/* we need the padding bottom here because if we don't have it the mobile footer will cut off...
4846 the dropshadow on the page... the padding is compensated by a negative top margin in mobile footer */}
···11+alter type public."pull_result" add attribute "draft_contributors" json;
22+33+set check_function_bodies = off;
44+55+CREATE OR REPLACE FUNCTION public.pull_data(token_id uuid, client_group_id text)
66+ RETURNS pull_result
77+ LANGUAGE plpgsql
88+AS $function$DECLARE
99+ result pull_result;
1010+BEGIN
1111+ -- Get client group data as JSON array
1212+ SELECT json_agg(row_to_json(rc))
1313+ FROM replicache_clients rc
1414+ WHERE rc.client_group = client_group_id
1515+ INTO result.client_groups;
1616+1717+ -- Get facts as JSON array
1818+ SELECT json_agg(row_to_json(f))
1919+ FROM permission_tokens pt,
2020+ get_facts(pt.root_entity) f
2121+ WHERE pt.id = token_id
2222+ INTO result.facts;
2323+2424+ -- Get publication data - try leaflets_in_publications first, then leaflets_to_documents
2525+ SELECT json_agg(row_to_json(lip))
2626+ FROM leaflets_in_publications lip
2727+ WHERE lip.leaflet = token_id
2828+ INTO result.publications;
2929+3030+ -- If no publication data found, try leaflets_to_documents (for standalone documents)
3131+ IF result.publications IS NULL THEN
3232+ SELECT json_agg(row_to_json(ltd))
3333+ FROM leaflets_to_documents ltd
3434+ WHERE ltd.leaflet = token_id
3535+ INTO result.publications;
3636+ END IF;
3737+3838+ -- Get the dids selected as contributors on this draft
3939+ SELECT json_agg(lc.contributor_did)
4040+ FROM leaflet_contributors lc
4141+ WHERE lc.leaflet = token_id
4242+ INTO result.draft_contributors;
4343+4444+ RETURN result;
4545+END;$function$
4646+;