Skip to content

Commit ffa43cd

Browse files
committed
walking together
1 parent fd2fcde commit ffa43cd

4 files changed

Lines changed: 166 additions & 39 deletions

File tree

website/events/events.tsx

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,3 +223,80 @@ export const Guestbook = withSharedState(
223223
);
224224
}
225225
);
226+
227+
interface SharedURL {
228+
url: string;
229+
userName: string;
230+
userColor: string;
231+
timestamp: number;
232+
}
233+
234+
export const URLChat = withSharedState(
235+
{
236+
defaultData: { urls: [] as SharedURL[] },
237+
},
238+
({ data, setData }) => {
239+
const [inputUrl, setInputUrl] = React.useState("");
240+
const urlListRef = React.useRef<HTMLDivElement>(null);
241+
242+
// Scroll to top (since we're using column-reverse) when new URLs are added
243+
React.useEffect(() => {
244+
if (urlListRef.current) {
245+
urlListRef.current.scrollTop = 0;
246+
}
247+
}, [data.urls]);
248+
249+
const handleSubmit = (e: React.FormEvent) => {
250+
const newUrl: SharedURL = {
251+
url: inputUrl,
252+
userName: window.cursors?.name || "Anonymous",
253+
userColor: window.cursors?.color || "#000000",
254+
timestamp: Date.now(),
255+
};
256+
257+
setData({ urls: [...data.urls, newUrl] });
258+
setInputUrl("");
259+
};
260+
261+
const copyToClipboard = () => {
262+
const text = data.urls
263+
.map(({ userName, url }) => `${userName}: ${url}`)
264+
.join("\n");
265+
navigator.clipboard.writeText(text);
266+
};
267+
268+
return (
269+
<div className="url-chat">
270+
<div className="url-list" ref={urlListRef}>
271+
{[...data.urls].reverse().map((urlData, i) => (
272+
<div key={i} className="url-entry">
273+
<span className="timestamp">
274+
{new Date(urlData.timestamp).toLocaleTimeString()}
275+
</span>
276+
<span className="username" style={{ color: urlData.userColor }}>
277+
{urlData.userName}:
278+
</span>
279+
<a href={urlData.url} target="_blank" rel="noopener noreferrer">
280+
{urlData.url}
281+
</a>
282+
</div>
283+
))}
284+
</div>
285+
<form onSubmit={handleSubmit}>
286+
<input
287+
type="url"
288+
value={inputUrl}
289+
onChange={(e) => setInputUrl(e.target.value)}
290+
placeholder="Share a URL"
291+
/>
292+
<button type="submit">Share</button>
293+
</form>
294+
{data.urls.length > 0 && (
295+
<button onClick={copyToClipboard} style={{ marginTop: "0.5em" }}>
296+
Copy All URLs
297+
</button>
298+
)}
299+
</div>
300+
);
301+
}
302+
);

website/events/walking-together/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
1010
<link
11-
href="https://fonts.googleapis.com/css2?family=Carter+One&family=Play:wght@400;700display=swap"
11+
href="https://fonts.googleapis.com/css2?family=Carter+One&family=Play:wght@400;700&family=Cousine:wght@400;700&display=swap"
1212
rel="stylesheet"
1313
/>
1414

website/events/walking-together/walking-together.scss

Lines changed: 63 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1+
$mono-font: "Cousine", "Courier", monospace;
2+
13
html,
24
body {
35
margin: 0;
46
padding: 0;
57
height: 100%;
68
overflow: hidden;
7-
font-family: "Play";
9+
font-family: "Times";
810
background: #f0f0f0;
11+
font-size: 16px;
912
}
1013

1114
.walking-together {
@@ -30,43 +33,57 @@ body {
3033

3134
input[type="text"] {
3235
padding: 0.5em;
33-
font-family: monospace;
36+
font-family: $mono-font;
3437
}
3538
}
3639

3740
.url-chat {
41+
font-size: 14px;
3842
position: fixed;
3943
top: 50%;
4044
left: 50%;
4145
transform: translate(-50%, -50%);
4246
width: 450px;
43-
// max-width: 600px;
47+
height: 450px;
4448
z-index: 10;
45-
46-
form {
47-
display: flex;
48-
gap: 0.5em;
49-
margin-bottom: 0.5em;
50-
51-
input {
52-
flex: 1;
53-
padding: 0.5em;
54-
font-family: monospace;
55-
}
56-
}
49+
display: flex;
50+
flex-direction: column;
5751

5852
.url-list {
53+
flex: 1;
5954
border: 1px solid #ccc;
60-
height: 200px;
6155
overflow-y: auto;
6256
padding: 1em;
63-
font-family: monospace;
57+
font-family: $mono-font;
6458
background: #fff;
59+
display: flex;
60+
flex-direction: column-reverse;
61+
justify-content: flex-start;
62+
63+
/* Hide scrollbar for Chrome, Safari and Opera */
64+
&::-webkit-scrollbar {
65+
width: 6px;
66+
}
67+
68+
&::-webkit-scrollbar-track {
69+
background: #f1f1f1;
70+
}
71+
72+
&::-webkit-scrollbar-thumb {
73+
background: #888;
74+
border-radius: 3px;
75+
}
76+
77+
/* For Firefox */
78+
scrollbar-width: thin;
79+
scrollbar-color: #888 #f1f1f1;
6580
}
6681

6782
.url-entry {
68-
margin: 0.5em 0;
83+
margin: 0;
84+
padding: 0.25em 0;
6985
word-break: break-all;
86+
animation: fadeIn 0.3s ease-in-out;
7087
}
7188

7289
.timestamp {
@@ -78,6 +95,32 @@ body {
7895
.username {
7996
margin-right: 0.5em;
8097
}
98+
99+
form {
100+
display: flex;
101+
gap: 0.5em;
102+
padding: 0.5em;
103+
background: white;
104+
border: 1px solid #ccc;
105+
border-top: none;
106+
107+
input {
108+
flex: 1;
109+
padding: 0.5em;
110+
font-family: $mono-font;
111+
}
112+
}
113+
}
114+
115+
@keyframes fadeIn {
116+
from {
117+
opacity: 0;
118+
transform: translateY(-10px);
119+
}
120+
to {
121+
opacity: 1;
122+
transform: translateY(0);
123+
}
81124
}
82125

83126
.group-activity {
@@ -97,11 +140,11 @@ body {
97140
.instruction {
98141
font-size: 1.5em;
99142
margin: 0;
100-
font-weight: bold;
143+
font-style: italic;
101144
}
102145

103146
.countdown {
104-
font-family: monospace;
147+
font-family: $mono-font;
105148
color: #666;
106149
margin-top: 0.5em;
107150
font-size: 0.9em;

website/events/walking-together/walking-together.tsx

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -129,10 +129,10 @@ export const URLChat = withSharedState(
129129
const [inputUrl, setInputUrl] = React.useState("");
130130
const urlListRef = React.useRef<HTMLDivElement>(null);
131131

132-
// Scroll to bottom when new URLs are added
132+
// Scroll to top (since we're using column-reverse) when new URLs are added
133133
React.useEffect(() => {
134134
if (urlListRef.current) {
135-
urlListRef.current.scrollTop = urlListRef.current.scrollHeight;
135+
urlListRef.current.scrollTop = 0;
136136
}
137137
}, [data.urls]);
138138

@@ -162,18 +162,19 @@ export const URLChat = withSharedState(
162162
};
163163

164164
return (
165-
<div className="url-chat">
166-
<form onSubmit={handleSubmit}>
167-
<input
168-
type="url"
169-
value={inputUrl}
170-
onChange={(e) => setInputUrl(e.target.value)}
171-
placeholder="Share a URL"
172-
/>
173-
<button type="submit">Share</button>
174-
</form>
165+
<div className="url-chat" id="url-chat">
166+
<div
167+
style={{
168+
position: "absolute",
169+
right: 0,
170+
}}
171+
>
172+
{data.urls.length > 0 && (
173+
<button onClick={copyToClipboard}>Copy All URLs</button>
174+
)}
175+
</div>
175176
<div className="url-list" ref={urlListRef}>
176-
{data.urls.map((urlData, i) => (
177+
{[...data.urls].reverse().map((urlData, i) => (
177178
<div key={i} className="url-entry">
178179
<span className="timestamp">
179180
{new Date(urlData.timestamp).toLocaleTimeString()}
@@ -187,9 +188,15 @@ export const URLChat = withSharedState(
187188
</div>
188189
))}
189190
</div>
190-
{/* {data.urls.length > 0 && (
191-
<button onClick={copyToClipboard}>Copy All URLs</button>
192-
)} */}
191+
<form onSubmit={handleSubmit}>
192+
<input
193+
type="url"
194+
value={inputUrl}
195+
onChange={(e) => setInputUrl(e.target.value)}
196+
placeholder="Share a URL"
197+
/>
198+
<button type="submit">Share</button>
199+
</form>
193200
</div>
194201
);
195202
}
@@ -231,13 +238,13 @@ export const GroupActivityDisplay = withSharedState(
231238
const seconds = timeLeft % 60;
232239

233240
return (
234-
<div className="group-activity">
241+
<div className="group-activity" id="group-activity">
235242
<h3>Current Activity:</h3>
236243
<p className="instruction">
237244
{CURSOR_INSTRUCTIONS[data.currentInstructionIndex]}
238245
</p>
239246
<p className="countdown">
240-
Next activity in: {minutes}:{seconds.toString().padStart(2, "0")}
247+
{minutes}:{seconds.toString().padStart(2, "0")}
241248
</p>
242249
</div>
243250
);

0 commit comments

Comments
 (0)