1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
const DEFAULT_FRONTEND_MODULE = "https://esm.town/v/dglazkov/bbrunfe";
/**
* You can supply these options as a second argument to the `proxy` function.
* These options are used to configure the frontend.
*/
export type FrontendOptions = {
/**
* The frontend module to render.
* If undefined, the default frontend will be used.
* If false, no frontend will be used.
*/
frontend?: false | string;
/**
* The style of the frontend.
*/
style?: {
/**
* The background color of the frontend.
* If undefined, the default is ""#f0f0f0"
*/
bg?: string;
/**
* The font family that will be used for text.
* If undefined, the default is "Helvetica Neue, Helvetica, Arial, sans-serif"
*/
fontFamily?: string;
/**
* The primary color used by the frontend.
* If undefined, the default is "#3498db"
*/
colorPrimary?: string;
/**
* The background color of the primary color.
* If undefined, the default is "#fff"
*/
colorPrimaryBg?: string;
/**
* The error color used by the frontend.
* If undefined, the default is "#fff0f0"
*/
colorError?: string;
};
};
const renderFrontend = (board: string, options?: FrontendOptions) => {
if (options && options.frontend === false) {
return new Response("Method not allowed", { status: 405 });
}
const chatAppModule = (options && options.frontend)
|| DEFAULT_FRONTEND_MODULE;
const bg = options?.style?.bg || "#f0f0f0";
const fontFamily = options?.style?.fontFamily
|| "Helvetica Neue, Helvetica, Arial, sans-serif";
const colorPrimary = options?.style?.colorPrimary || "#3498db";
const colorPrimaryBg = options?.style?.colorPrimaryBg || "#fff";
const colorError = options?.style?.colorError || "#fff0f0";
const page = `<!doctype html><head>
<meta charset="utf-8">
<link rel="board" href="${board}">
<meta name="viewport" content="width=device-width">
<style>
:root {
--ca-color-bg: ${bg};
--ca-font-family: ${fontFamily};
--ca-color-primary: ${colorPrimary};
--ca-color-primary-bg: ${colorPrimaryBg};
--ca-color-error: ${colorError};
}
body, html {
height: 100%;
margin: 0;
font-family: var(--ca-font-family);
background-color: var(--ca-color-bg);
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
}
body {
padding: 2rem;
width: 100%;
}
</style>
<script type="module" src="${chatAppModule}"></script>
</head>
<body>
<chat-app></chat-app>
</body>`;
return new Response(page, {
headers: {
"Content-Type": "text/html",
},
});
};