+2
app/(home-pages)/home/Actions/CreateNewButton.tsx
+2
app/(home-pages)/home/Actions/CreateNewButton.tsx
+3
-24
app/(home-pages)/home/HomeLayout.tsx
+3
-24
app/(home-pages)/home/HomeLayout.tsx
···
1
1
"use client";
2
2
3
-
import { getHomeDocs, HomeDoc } from "./storage";
3
+
import { getHomeDocs } from "./storage";
4
4
import useSWR from "swr";
5
5
import {
6
6
Fact,
···
13
13
import type { Attribute } from "src/replicache/attributes";
14
14
import { callRPC } from "app/api/rpc/client";
15
15
import { StaticLeafletDataContext } from "components/PageSWRDataProvider";
16
-
import { HomeSmall } from "components/Icons/HomeSmall";
17
16
import {
18
17
HomeDashboardControls,
19
18
DashboardLayout,
···
22
21
} from "components/PageLayouts/DashboardLayout";
23
22
import { Actions } from "./Actions/Actions";
24
23
import { useCardBorderHidden } from "components/Pages/useCardBorderHidden";
25
-
import { Json } from "supabase/database.types";
26
24
import { useTemplateState } from "./Actions/CreateNewButton";
27
-
import { CreateNewLeafletButton } from "./Actions/CreateNewButton";
28
-
import { ActionButton } from "components/ActionBar/ActionButton";
29
-
import { AddTiny } from "components/Icons/AddTiny";
30
-
import {
31
-
get_leaflet_data,
32
-
GetLeafletDataReturnType,
33
-
} from "app/api/rpc/[command]/get_leaflet_data";
34
-
import { useEffect, useRef, useState } from "react";
35
-
import { Input } from "components/Input";
25
+
import { GetLeafletDataReturnType } from "app/api/rpc/[command]/get_leaflet_data";
26
+
import { useState } from "react";
36
27
import { useDebouncedEffect } from "src/hooks/useDebouncedEffect";
37
-
import {
38
-
ButtonPrimary,
39
-
ButtonSecondary,
40
-
ButtonTertiary,
41
-
} from "components/Buttons";
42
-
import { AddSmall } from "components/Icons/AddSmall";
43
-
import { PublishIllustration } from "app/[leaflet_id]/publish/PublishIllustration/PublishIllustration";
44
-
import { PubListEmptyIllo } from "components/ActionBar/Publications";
45
-
import { theme } from "tailwind.config";
46
-
import Link from "next/link";
47
-
import { DiscoverIllo } from "./HomeEmpty/DiscoverIllo";
48
-
import { WelcomeToLeafletIllo } from "./HomeEmpty/WelcomeToLeafletIllo";
49
28
import {
50
29
DiscoverBanner,
51
30
HomeEmptyState,
+5
app/globals.css
+5
app/globals.css
···
96
96
--accent-2: 255, 255, 255;
97
97
--accent-contrast: 0, 0, 225;
98
98
--accent-1-is-contrast: "true";
99
+
--accent-light: color-mix(
100
+
in oklab,
101
+
rgb(var(--accent-contrast)),
102
+
rgb(var(--bg-page)) 85%
103
+
);
99
104
100
105
--highlight-1: 255, 177, 177;
101
106
--highlight-2: 253, 245, 203;
+14
-11
app/login/LoginForm.tsx
+14
-11
app/login/LoginForm.tsx
···
13
13
import { useSmoker, useToaster } from "components/Toast";
14
14
import React, { useState } from "react";
15
15
import { mutate } from "swr";
16
+
import { BlueskyTiny } from "components/Icons/BlueskyTiny";
16
17
17
18
export default function LoginForm(props: {
18
19
noEmail?: boolean;
···
167
168
export function BlueskyLogin(props: {
168
169
redirectRoute?: string;
169
170
action?: ActionAfterSignIn;
171
+
compact?: boolean;
170
172
}) {
171
173
const [signingWithHandle, setSigningWithHandle] = useState(false);
172
174
const [handle, setHandle] = useState("");
···
186
188
/>
187
189
)}
188
190
{signingWithHandle ? (
189
-
<div className="w-full flex flex-col gap-2">
191
+
<div className="w-full flex gap-1">
190
192
<Input
191
193
type="text"
192
194
name="handle"
···
197
199
onChange={(e) => setHandle(e.target.value)}
198
200
required
199
201
/>
200
-
<ButtonPrimary type="submit" fullWidth className="py-2">
201
-
<BlueskySmall />
202
-
Sign In
203
-
</ButtonPrimary>
202
+
<ButtonPrimary type="submit">Sign In</ButtonPrimary>
204
203
</div>
205
204
) : (
206
-
<div className="flex flex-col">
207
-
<ButtonPrimary fullWidth className="py-2">
208
-
<BlueskySmall />
209
-
Log In/Sign Up with Bluesky
205
+
<div className="flex flex-col justify-center">
206
+
<ButtonPrimary
207
+
fullWidth={!props.compact}
208
+
compact={props.compact}
209
+
className={`${props.compact ? "mx-auto text-sm" : "py-2"}`}
210
+
>
211
+
{props.compact ? <BlueskyTiny /> : <BlueskySmall />}
212
+
{props.compact ? "Link" : "Log In/Sign Up with"} Bluesky
210
213
</ButtonPrimary>
211
214
<button
212
215
type="button"
213
-
className="text-sm text-accent-contrast place-self-center mt-[6px]"
216
+
className={`${props.compact ? "text-xs" : "text-sm"} text-accent-contrast place-self-center mt-[6px]`}
214
217
onClick={() => setSigningWithHandle(true)}
215
218
>
216
-
or use an ATProto handle
219
+
use an ATProto handle
217
220
</button>
218
221
</div>
219
222
)}
+73
-8
components/ActionBar/Publications.tsx
+73
-8
components/ActionBar/Publications.tsx
···
10
10
import { ActionButton } from "./ActionButton";
11
11
import { SpeedyLink } from "components/SpeedyLink";
12
12
import { PublishSmall } from "components/Icons/PublishSmall";
13
+
import { Popover } from "components/Popover";
14
+
import { BlueskyLogin } from "app/login/LoginForm";
15
+
import { ButtonPrimary } from "components/Buttons";
16
+
import { useIsMobile } from "src/hooks/isMobile";
17
+
import { useState } from "react";
13
18
14
19
export const PublicationButtons = (props: {
15
20
currentPubUri: string | undefined;
···
18
23
19
24
// don't show pub list button if not logged in or no pub list
20
25
// we show a "start a pub" banner instead
21
-
if (!identity || !identity.atp_did) return <PubListEmpty />;
26
+
if (!identity || !identity.atp_did || identity.publications.length === 0)
27
+
return <PubListEmpty />;
22
28
return (
23
29
<div className="pubListWrapper w-full flex flex-col gap-1 sm:bg-transparent sm:border-0">
24
30
{identity.publications?.map((d) => {
25
-
// console.log("thisURI : " + d.uri);
26
-
// console.log("currentURI : " + props.currentPubUri);
27
-
28
31
return (
29
32
<PublicationOption
30
33
{...d}
···
78
81
};
79
82
80
83
const PubListEmpty = () => {
81
-
return (
82
-
<SpeedyLink href={`lish/createPub`} className=" hover:no-underline!">
84
+
let { identity } = useIdentityData();
85
+
let isMobile = useIsMobile();
86
+
87
+
let [state, setState] = useState<"default" | "info">("default");
88
+
if (isMobile && state == "default")
89
+
return (
83
90
<ActionButton
84
91
label="Publish"
85
92
icon={<PublishSmall />}
86
93
nav
87
-
subtext="Blog on ATProto!"
94
+
subtext="Start a blog on ATProto!"
95
+
onClick={() => {
96
+
setState("info");
97
+
}}
88
98
/>
89
-
</SpeedyLink>
99
+
);
100
+
101
+
if (isMobile && state === "info") return <PublishPopoverContent />;
102
+
else
103
+
return (
104
+
<Popover
105
+
side="right"
106
+
align="start"
107
+
className="p-1! max-w-56"
108
+
trigger={
109
+
<ActionButton
110
+
label="Publish"
111
+
icon={<PublishSmall />}
112
+
nav
113
+
subtext="Start a blog on ATProto!"
114
+
/>
115
+
}
116
+
>
117
+
<PublishPopoverContent />
118
+
</Popover>
119
+
);
120
+
};
121
+
122
+
const PublishPopoverContent = () => {
123
+
let { identity } = useIdentityData();
124
+
125
+
return (
126
+
<div className="bg-[var(--accent-light)] w-full rounded-md flex flex-col text-center justify-center p-2 pb-4 text-sm">
127
+
<div className="mx-auto pt-2 scale-90">
128
+
<PubListEmptyIllo />
129
+
</div>
130
+
<div className="pt-1 font-bold">Publish on AT Proto</div>
131
+
{identity && identity.atp_did ? (
132
+
// has ATProto account and no pubs
133
+
<>
134
+
<div className="pb-2 text-secondary text-xs">
135
+
Start a new publication <br />
136
+
on AT Proto
137
+
</div>
138
+
<SpeedyLink href={`lish/createPub`} className=" hover:no-underline!">
139
+
<ButtonPrimary className="text-sm mx-auto" compact>
140
+
Start a Publication!
141
+
</ButtonPrimary>
142
+
</SpeedyLink>
143
+
</>
144
+
) : (
145
+
// no ATProto account and no pubs
146
+
<>
147
+
<div className="pb-2 text-secondary text-xs">
148
+
Link a Bluesky account to start a new publication on AT Proto
149
+
</div>
150
+
151
+
<BlueskyLogin compact />
152
+
</>
153
+
)}
154
+
</div>
90
155
);
91
156
};
92
157