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
27
pulls
pipelines
add domain input to create pub form
awarm.space
10 months ago
9af6ece6
0bdfafb2
+62
-15
7 changed files
expand all
collapse all
unified
split
app
api
rpc
[command]
domain_routes.ts
route.ts
lish
createPub
CreatePubForm.tsx
lexicons
api
lexicons.ts
types
pub
leaflet
publication.ts
pub
leaflet
publication.json
src
publication.ts
+28
app/api/rpc/[command]/domain_routes.ts
···
1
1
import { z } from "zod";
2
2
import { makeRoute } from "../lib";
3
3
import type { Env } from "./route";
4
4
+
import { NextApiResponse } from "next";
4
5
5
6
export const get_domain_status = makeRoute({
6
7
route: "get_domain_status",
···
21
22
]);
22
23
return { status, config };
23
24
} catch (e) {
25
25
+
console.log(e);
26
26
+
let errorResponse = e as NextApiResponse;
27
27
+
if (errorResponse.statusCode === 404)
28
28
+
return { error: "Not Found" } as const;
29
29
+
return { error: true };
30
30
+
}
31
31
+
},
32
32
+
});
33
33
+
34
34
+
export const get_leaflet_subdomain_status = makeRoute({
35
35
+
route: "get_leaflet_subdomain_status",
36
36
+
input: z.object({
37
37
+
domain: z.string(),
38
38
+
}),
39
39
+
handler: async ({ domain }, { vercel }: Pick<Env, "vercel">) => {
40
40
+
try {
41
41
+
let c = await vercel.projects.getProjectDomain({
42
42
+
idOrName: "prj_9jX4tmYCISnm176frFxk07fF74kG",
43
43
+
teamId: "team_42xaJiZMTw9Sr7i0DcLTae9d",
44
44
+
domain: `${domain}.leaflet.pub`,
45
45
+
});
46
46
+
return { config: c };
47
47
+
} catch (e) {
48
48
+
console.log(e);
49
49
+
let errorResponse = e as NextApiResponse;
50
50
+
if (errorResponse.statusCode === 404)
51
51
+
return { error: "Not Found" } as const;
24
52
return { error: true };
25
53
}
26
54
},
+5
-1
app/api/rpc/[command]/route.ts
···
7
7
import { pull } from "./pull";
8
8
import { getFactsFromHomeLeaflets } from "./getFactsFromHomeLeaflets";
9
9
import { Vercel } from "@vercel/sdk";
10
10
-
import { get_domain_status } from "./domain_routes";
10
10
+
import {
11
11
+
get_domain_status,
12
12
+
get_leaflet_subdomain_status,
13
13
+
} from "./domain_routes";
11
14
import { get_leaflet_data } from "./get_leaflet_data";
12
15
import { get_publication_data } from "./get_publication_data";
13
16
···
33
36
pull,
34
37
getFactsFromHomeLeaflets,
35
38
get_domain_status,
39
39
+
get_leaflet_subdomain_status,
36
40
get_leaflet_data,
37
41
get_publication_data,
38
42
];
+25
-10
app/lish/createPub/CreatePubForm.tsx
···
31
31
iconFile: logoFile,
32
32
});
33
33
router.push(
34
34
-
`/lish/${identity?.resolved_did?.alsoKnownAs?.[0].slice(5)}/${nameValue}/`,
34
34
+
`/lish/${identity?.resolved_did?.alsoKnownAs?.[0].slice(5)}/${nameValue}/dashboard`,
35
35
);
36
36
}}
37
37
>
···
111
111
setState("normal");
112
112
}, [props.domain]);
113
113
useDebouncedEffect(
114
114
-
() => {
115
115
-
let status = callRPC("get_domain_status", { domain: props.domain });
114
114
+
async () => {
115
115
+
if (!props.domain) return setState("normal");
116
116
+
let status = await callRPC("get_leaflet_subdomain_status", {
117
117
+
domain: props.domain,
118
118
+
});
116
119
console.log(status);
120
120
+
if (status.error === "Not Found") setState("valid");
121
121
+
else setState("invalid");
117
122
},
118
123
500,
119
124
[props.domain],
120
125
);
121
126
return (
122
122
-
<div className="flex flex-row gap-1">
123
123
-
<Input
124
124
-
value={props.domain}
125
125
-
onChange={(e) => props.setDomain(e.currentTarget.value)}
126
126
-
/>
127
127
-
.leaflet.pub
128
128
-
</div>
127
127
+
<label className=" input-with-border flex flex-col text-sm text-tertiary font-bold italic leading-tight !py-1 !px-[6px]">
128
128
+
<div>Domain</div>
129
129
+
<div className="flex flex-row items-center">
130
130
+
<Input
131
131
+
placeholder="domain"
132
132
+
className="appearance-none w-full font-normal bg-transparent text-base text-primary focus:outline-0 outline-none"
133
133
+
value={props.domain}
134
134
+
onChange={(e) => props.setDomain(e.currentTarget.value)}
135
135
+
/>
136
136
+
.leaflet.pub
137
137
+
</div>
138
138
+
{state === "valid"
139
139
+
? "Available!"
140
140
+
: state === "invalid"
141
141
+
? "Unavailable"
142
142
+
: null}
143
143
+
</label>
129
144
);
130
145
}
+1
-1
lexicons/api/lexicons.ts
···
74
74
type: 'string',
75
75
maxLength: 2000,
76
76
},
77
77
-
domain: {
77
77
+
base_path: {
78
78
type: 'string',
79
79
format: 'uri',
80
80
},
+1
-1
lexicons/api/types/pub/leaflet/publication.ts
···
13
13
export interface Record {
14
14
$type: 'pub.leaflet.publication'
15
15
name: string
16
16
-
domain?: string
16
16
+
base_path?: string
17
17
description?: string
18
18
icon?: BlobRef
19
19
[k: string]: unknown
+1
-1
lexicons/pub/leaflet/publication.json
···
16
16
"type": "string",
17
17
"maxLength": 2000
18
18
},
19
19
-
"domain": {
19
19
+
"base_path": {
20
20
"type": "string",
21
21
"format": "uri"
22
22
},
+1
-1
lexicons/src/publication.ts
···
13
13
required: ["name"],
14
14
properties: {
15
15
name: { type: "string", maxLength: 2000 },
16
16
-
domain: { type: "string", format: "uri" },
16
16
+
base_path: { type: "string", format: "uri" },
17
17
description: { type: "string", maxLength: 2000 },
18
18
icon: { type: "blob", accept: ["image/*"], maxSize: 1000000 },
19
19
},