tangled
alpha
login
or
join now
leaflet.pub
/
leaflet
289
fork
atom
a tool for shared writing and social publishing
289
fork
atom
overview
issues
28
pulls
pipelines
started up on the publish button, WIP
cozylittle.house
4 months ago
17589eb9
c3407e44
+102
-41
3 changed files
expand all
collapse all
unified
split
app
[leaflet_id]
Sidebar.tsx
actions
PublishButton.tsx
components
ActionBar
Publications.tsx
+7
-24
app/[leaflet_id]/Sidebar.tsx
···
1
1
"use client";
2
2
-
import { ActionButton } from "components/ActionBar/ActionButton";
3
2
import { Sidebar } from "components/ActionBar/Sidebar";
4
3
import { useEntitySetContext } from "components/EntitySetProvider";
5
4
import { HelpButton } from "app/[leaflet_id]/actions/HelpButton";
···
10
9
import { ThemePopover } from "components/ThemeManager/ThemeSetter";
11
10
import { PublishButton } from "./actions/PublishButton";
12
11
import { Watermark } from "components/Watermark";
13
13
-
import { useUIState } from "src/useUIState";
14
12
import { BackToPubButton } from "./actions/BackToPubButton";
15
13
import { useIdentityData } from "components/IdentityProvider";
16
14
import { useReplicache } from "src/replicache";
···
30
28
<div className="sidebarContainer flex flex-col justify-end h-full w-16 relative">
31
29
{entity_set.permissions.write && (
32
30
<Sidebar>
31
31
+
<PublishButton />
32
32
+
<ShareOptions />
33
33
+
<ThemePopover entityID={rootEntity} />
34
34
+
<HelpButton />
35
35
+
<hr className="text-border" />
33
36
{pub?.publications &&
34
37
identity?.atp_did &&
35
38
pub.publications.identity_did === identity.atp_did ? (
36
36
-
<>
37
37
-
<PublishButton />
38
38
-
<ShareOptions />
39
39
-
<ThemePopover entityID={rootEntity} />
40
40
-
<HelpButton />
41
41
-
<hr className="text-border" />
42
42
-
<BackToPubButton publication={pub.publications} />
43
43
-
</>
39
39
+
<BackToPubButton publication={pub.publications} />
44
40
) : (
45
45
-
<>
46
46
-
<ShareOptions />
47
47
-
<ThemePopover entityID={rootEntity} />
48
48
-
<HelpButton />
49
49
-
<hr className="text-border" />
50
50
-
<HomeButton />
51
51
-
</>
41
41
+
<HomeButton />
52
42
)}
53
43
</Sidebar>
54
44
)}
···
60
50
</Media>
61
51
);
62
52
}
63
63
-
64
64
-
const blurPage = () => {
65
65
-
useUIState.setState(() => ({
66
66
-
focusedEntity: null,
67
67
-
selectedBlocks: [],
68
68
-
}));
69
69
-
};
+89
-10
app/[leaflet_id]/actions/PublishButton.tsx
···
1
1
import { publishToPublication } from "actions/publishToPublication";
2
2
import { getPublicationURL } from "app/lish/createPub/getPublicationURL";
3
3
import { ActionButton } from "components/ActionBar/ActionButton";
4
4
+
import {
5
5
+
PubIcon,
6
6
+
PubListEmptyContent,
7
7
+
} from "components/ActionBar/Publications";
8
8
+
import { ArchiveSmall } from "components/Icons/ArchiveSmall";
4
9
import { PublishSmall } from "components/Icons/PublishSmall";
10
10
+
import { useIdentityData } from "components/IdentityProvider";
11
11
+
import { Menu, MenuItem } from "components/Layout";
5
12
import { useLeafletPublicationData } from "components/PageSWRDataProvider";
13
13
+
import { Popover } from "components/Popover";
6
14
import { SpeedyLink } from "components/SpeedyLink";
7
15
import { useToaster } from "components/Toast";
8
16
import { DotLoader } from "components/utils/DotLoader";
9
9
-
import { useParams } from "next/navigation";
10
10
-
import { useRouter } from "next/router";
17
17
+
import { PubLeafletPublication } from "lexicons/api";
18
18
+
import { useParams, useRouter } from "next/navigation";
11
19
import { useState } from "react";
20
20
+
import { useIsMobile } from "src/hooks/isMobile";
12
21
import { useReplicache } from "src/replicache";
13
22
14
23
export const PublishButton = () => {
15
24
let { data: pub } = useLeafletPublicationData();
16
25
let params = useParams();
17
26
let router = useRouter();
18
18
-
if (!pub)
19
19
-
return (
20
20
-
<ActionButton
21
21
-
primary
22
22
-
icon={<PublishSmall className="shrink-0" />}
23
23
-
label={"Publish on ATP"}
24
24
-
/>
25
25
-
);
27
27
+
28
28
+
if (!pub) return <PublishToPublication />;
26
29
if (!pub?.doc)
27
30
return (
28
31
<ActionButton
···
78
81
/>
79
82
);
80
83
};
84
84
+
85
85
+
const PublishToPublication = () => {
86
86
+
let { identity } = useIdentityData();
87
87
+
let params = useParams();
88
88
+
let router = useRouter();
89
89
+
let isMobile = useIsMobile();
90
90
+
let hasPubs =
91
91
+
identity && identity.atp_did && identity.publications.length > 0;
92
92
+
93
93
+
if (!hasPubs)
94
94
+
return (
95
95
+
<Menu
96
96
+
asChild
97
97
+
side={isMobile ? "top" : "right"}
98
98
+
align={isMobile ? "center" : "start"}
99
99
+
className="flex flex-col max-w-xs text-secondary"
100
100
+
trigger={
101
101
+
<ActionButton
102
102
+
primary
103
103
+
icon={<PublishSmall className="shrink-0" />}
104
104
+
label={"Publish on ATP"}
105
105
+
/>
106
106
+
}
107
107
+
>
108
108
+
<div className="text-sm text-tertiary">Publish to…</div>
109
109
+
{identity?.publications?.map((d) => {
110
110
+
return (
111
111
+
<MenuItem
112
112
+
onSelect={async () => {
113
113
+
// TODO
114
114
+
// make this a draft of the selected Publication
115
115
+
// redirect to the publication publish page
116
116
+
}}
117
117
+
>
118
118
+
<PubIcon
119
119
+
record={d.record as PubLeafletPublication.Record}
120
120
+
uri={d.uri}
121
121
+
/>
122
122
+
<div className=" w-full truncate font-bold">{d.name}</div>
123
123
+
</MenuItem>
124
124
+
);
125
125
+
})}
126
126
+
<hr className="border-border-light my-1" />
127
127
+
<MenuItem
128
128
+
onSelect={() => {
129
129
+
// TODO
130
130
+
// send to one-off /publish page
131
131
+
}}
132
132
+
>
133
133
+
<ArchiveSmall />
134
134
+
<div className="font-bold pb-1">Publish as One-Off</div>
135
135
+
</MenuItem>
136
136
+
</Menu>
137
137
+
);
138
138
+
else
139
139
+
return (
140
140
+
<Popover
141
141
+
asChild
142
142
+
side={isMobile ? "top" : "right"}
143
143
+
align={isMobile ? "center" : "start"}
144
144
+
className="p-1!"
145
145
+
trigger={
146
146
+
<ActionButton
147
147
+
primary
148
148
+
icon={<PublishSmall className="shrink-0" />}
149
149
+
label={"Publish on ATP"}
150
150
+
/>
151
151
+
}
152
152
+
>
153
153
+
{/* this component is also used on Home to populate the sidebar when PubList is empty */}
154
154
+
{/* however, this component needs to redirect to sign in, pub creation, AND publish so we might need to just make a new component */}
155
155
+
156
156
+
<PubListEmptyContent />
157
157
+
</Popover>
158
158
+
);
159
159
+
};
+6
-7
components/ActionBar/Publications.tsx
···
12
12
import { PublishSmall } from "components/Icons/PublishSmall";
13
13
import { Popover } from "components/Popover";
14
14
import { BlueskyLogin } from "app/login/LoginForm";
15
15
-
import { ButtonPrimary } from "components/Buttons";
15
15
+
import { ButtonSecondary } from "components/Buttons";
16
16
import { useIsMobile } from "src/hooks/isMobile";
17
17
import { useState } from "react";
18
18
···
81
81
};
82
82
83
83
const PubListEmpty = () => {
84
84
-
let { identity } = useIdentityData();
85
84
let isMobile = useIsMobile();
86
85
87
86
let [state, setState] = useState<"default" | "info">("default");
···
98
97
/>
99
98
);
100
99
101
101
-
if (isMobile && state === "info") return <PublishPopoverContent />;
100
100
+
if (isMobile && state === "info") return <PubListEmptyContent />;
102
101
else
103
102
return (
104
103
<Popover
···
114
113
/>
115
114
}
116
115
>
117
117
-
<PublishPopoverContent />
116
116
+
<PubListEmptyContent />
118
117
</Popover>
119
118
);
120
119
};
121
120
122
122
-
const PublishPopoverContent = () => {
121
121
+
export const PubListEmptyContent = () => {
123
122
let { identity } = useIdentityData();
124
123
125
124
return (
···
136
135
on AT Proto
137
136
</div>
138
137
<SpeedyLink href={`lish/createPub`} className=" hover:no-underline!">
139
139
-
<ButtonPrimary className="text-sm mx-auto" compact>
138
138
+
<ButtonSecondary className="text-sm mx-auto" compact>
140
139
Start a Publication!
141
141
-
</ButtonPrimary>
140
140
+
</ButtonSecondary>
142
141
</SpeedyLink>
143
142
</>
144
143
) : (