Skip to content

Commit d43c810

Browse files
authored
Merge pull request #65 from SolidLabResearch/eliasnijs-polishing
polishing
2 parents 7b29ff1 + 7e8cade commit d43c810

31 files changed

Lines changed: 7068 additions & 2717 deletions

solid-watchparty/github-post-build-script.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import * as fs from "fs";
33

44
const routes = [
55
"/menu",
6-
"/watch"
6+
"/watch",
7+
"/auth",
78
];
89
const dir = viteConfig.build.outDir;
910
for (const route of routes) {

solid-watchparty/package-lock.json

Lines changed: 6008 additions & 2432 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

solid-watchparty/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
},
1313
"dependencies": {
1414
"@comunica/query-sparql-link-traversal": "^0.3.0",
15+
"@comunica/query-sparql-link-traversal-solid": "^0.4.0",
1516
"@comunica/query-sparql-solid": "^2.4.0",
1617
"@incremunica/query-sparql-incremental": "^1.2.0",
1718
"@inrupt/solid-client": "^1.30.2",

solid-watchparty/src/App.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ function App() {
2727
return (
2828
<SessionProvider>
2929
<MessageBoxContext.Provider value={messageBox}>
30-
<RouterProvider router={router}/>
30+
<RouterProvider router={router}/>
3131
</MessageBoxContext.Provider>
3232
</SessionProvider>
3333
);

solid-watchparty/src/components/SWChatComponent.jsx

Lines changed: 39 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -25,41 +25,53 @@ function SWChatComponent({roomUrl, joined}) {
2525
const [messages, setMessages] = useState([]);
2626
const sessionContext = useSession();
2727
const [messageBox,] = useContext(MessageBoxContext);
28+
const [userNames, setUserNames] = useState({});
2829

2930
useEffect(() => {
30-
let messageSeriesStreams = null;
31-
let messageStreams = [];
32-
let usernames = []
3331
const fetch = async () => {
34-
messageSeriesStreams = await MessageSolidService.getMessageSeriesStream(sessionContext, roomUrl);
32+
const messageSeriesStreams = await MessageSolidService.getMessageSeriesStream(sessionContext, roomUrl);
3533
if (messageSeriesStreams.error) {
3634
console.error(messageSeriesStreams.error)
3735
messageSeriesStreams = null;
3836
setState({isLoading: false, hasAccess: false});
3937
return;
4038
}
4139
messageSeriesStreams.on('data', async (data) => {
42-
let messageStream = await MessageSolidService.getMessageStream(sessionContext,
43-
data.get('messageSeries').value);
44-
const senderIndex = messageStreams.length;
45-
messageStreams.push(messageStream);
46-
47-
if (messageStream.error) {
40+
const messageSeries = data.get('messageSeries').value;
41+
42+
let senderName = "Unknown";
43+
let creatorUrlStream = await MessageSolidService.getMessageSeriesCreatorStream(sessionContext, messageSeries);
44+
creatorUrlStream.on('data', (data) => {
45+
const creatorUrl = data?.get('creator')?.value;
46+
UserSolidService.getName(sessionContext, creatorUrl).then((name) => {
47+
if (!name.error) {
48+
setUserNames((userNames) => {
49+
userNames[messageSeries] = name;
50+
return userNames;
51+
});
52+
}
53+
});
54+
});
55+
56+
// TODO(Elias): Switch out restart of stream when Incremunica has internal handling for this
57+
let messageStreamAuthCheck = await MessageSolidService.getMessageStream(sessionContext, messageSeries);
58+
messageStreamAuthCheck.on('data', async (data) => {
59+
messageStreamAuthCheck.close();
60+
});
61+
62+
let messageStream = await MessageSolidService.getMessageStream(sessionContext, messageSeries);
63+
if (!messageStream || messageStream.error) {
4864
messageStream = null;
4965
return;
5066
}
5167
messageStream.on('data', async (data) => {
52-
if (usernames.length <= senderIndex) {
53-
let name = await UserSolidService.getName(sessionContext, data.get('sender').value);
54-
name = (name.error) ? 'Unknown' : name;
55-
usernames.push(name);
56-
}
5768
const message = {
58-
text: data.get('text').value,
59-
sender: usernames[senderIndex],
60-
date: new Date(data.get('dateSent').value),
61-
key: (name + data.get('dateSent').value),
69+
text: data.get('text').value,
70+
messageBoxUrl: messageSeries,
71+
date: new Date(data.get('dateSent').value),
72+
key: (name + data.get('dateSent').value),
6273
};
74+
// TODO: Make this more efficient
6375
setMessages(messages => (
6476
[...messages, message]
6577
.sort((m1, m2) => (m1.date > m2.date) ? 1 : ((m1.date < m2.date) ? -1 : 0))
@@ -71,18 +83,6 @@ function SWChatComponent({roomUrl, joined}) {
7183
setState({isLoading: false, hasAccess: true});
7284
}
7385
fetch();
74-
75-
return (() => {
76-
if (messageSeriesStreams) {
77-
messageSeriesStreams.close();
78-
}
79-
for (let i = 0; i < messageStreams.length; i++) {
80-
if (messageStreams[i]) {
81-
messageStreams[i].close()
82-
}
83-
}
84-
setMessages([]);
85-
});
8686
}, [sessionContext.session, sessionContext.sessionRequestInProgress, roomUrl, joined])
8787

8888

@@ -120,13 +120,18 @@ function SWChatComponent({roomUrl, joined}) {
120120
pageContent = (
121121
<>
122122
<SWAutoScrollDiv className="overflow-y-auto overflow-x-auto mb-2 shrink">
123-
{messages.map((message) => <SWMessageComponent message={message} key={message.key}/>)}
123+
{messages.map((message) => {
124+
const sender = userNames[message.messageBoxUrl];
125+
return (
126+
<SWMessageComponent message={{...message, sender}} key={message.key}/>
127+
);
128+
})}
124129
</SWAutoScrollDiv>
125130
<form autoComplete="off" className="grow-0 flex flex-between items-center" onSubmit={submitMessage}>
126-
<input id="msgInput" className="px-2 h-10 rgb-bg-1 sw-border w-full"
131+
<input id="msgInput" className="px-2 h-10 rgb-bg-1 sw-border w-full border-solid"
127132
onChange={(e) => setInput(parseMessage(e.target.value))}
128133
value={input} type='text'/>
129-
<button className="sw-btn hidden"> P </button>
134+
<button className="sw-btn hidden"></button>
130135
</form>
131136
</>
132137
);

solid-watchparty/src/components/SWFooter.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
function SWFooter()
22
{
33
return (
4-
<div className="grow-0 p-8 flex flex-col justify-end text-center">
4+
<div className="p-8 flex flex-col justify-end text-center">
55
<p className="rgb-2">(c) IDLab 2023</p>
66
</div>
77
);

solid-watchparty/src/components/SWMessageComponent.jsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,18 @@ import { displayDate } from '../utils/general.js'
66

77
function MessageComponent({message})
88
{
9+
const sender = message.sender ? message.sender : "Name not found";
910
return (
10-
<div className="pb-2 flex">
11-
<div className="w-6 h-6 m-2 rgb-bg-3 rounded-max">
11+
<div className="pb-2 flex w-[90%]">
12+
<div className="w-6 min-w-6 h-6 m-2 rgb-bg-3 rounded-max">
1213
</div>
13-
<div className="pb-2">
14-
<div className="w-fit w-max flex items-baseline">
14+
<div className="pb-2 w-full">
15+
<div className="w-full flex items-baseline">
1516
<p className="sw-fw-1 mr-2">{message.sender}</p>
1617
<p className="rgb-2 text-sm">{displayDate(message.date)}</p>
1718
</div>
18-
<div className="rgb-1 w-fit w-max">
19-
<p>{message.text}</p>
19+
<div className="rgb-1 w">
20+
<p className="break-words">{message.text}</p>
2021
</div>
2122
</div>
2223
</div>

solid-watchparty/src/components/SWModal.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ function SWModal({children, className, setIsShown}) {
66
}
77
return (
88
<div className="fixed flex-col top-0 right-0 left-0 bottom-0 flex justify-center items-center z-50">
9-
<div onClick={outsideClicked} className="fixed top-0 right-0 left-0 bottom-0 rgb-bg-1 opacity-80"/>
9+
<div onClick={outsideClicked} className="fixed top-0 right-0 left-0 bottom-0 bg-[#000D]"/>
1010
<div className={className}>
1111
{children}
1212
</div>
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/* libary imports */
2+
import { useSession, } from '@inrupt/solid-ui-react';
3+
import { useState, useContext, useEffect, useRef } from 'react';
4+
import { useNavigate } from 'react-router-dom';
5+
import { FaMagnifyingGlass } from "react-icons/fa6";
6+
import { FaChevronRight } from 'react-icons/fa';
7+
8+
/* component imports */
9+
import SWPageWrapper from '../components/SWPageWrapper';
10+
import SWLoadingIcon from '../components/SWLoadingIcon';
11+
import SWModal from '../components/SWModal';
12+
import SWRoomPoster from '../components/SWRoomPoster';
13+
14+
/* service imports */
15+
import RoomSolidService from '../services/room.solidservice';
16+
import MessageSolidService from '../services/message.solidservice';
17+
18+
/* context imports */
19+
import { MessageBoxContext } from '../contexts';
20+
21+
/* util imports */
22+
import { validateAll, validateRequired, validateIsUrl, validateLength } from '../utils/validationUtils';
23+
import { displayDate } from '../utils/general';
24+
25+
/* config imports */
26+
import config from '../../config';
27+
28+
29+
function SWModalInputBar({setModalIsShown, title, f, args}) {
30+
const inputRef = useRef(null);
31+
32+
const [isLoading, setIsLoading] = useState(false);
33+
const [error, setError] = useState("");
34+
35+
36+
useEffect(() => {
37+
inputRef.current.focus();
38+
}, [isLoading]);
39+
40+
const onSubmit = async (e) => {
41+
e.preventDefault();
42+
if (isLoading) {
43+
return;
44+
}
45+
setIsLoading(true);
46+
const result = await f({
47+
input: inputRef.current.value,
48+
setError: setError,
49+
...args
50+
});
51+
if (result) {
52+
setError(result);
53+
}
54+
setIsLoading(false);
55+
}
56+
57+
const inputStyle =
58+
(isLoading) ? "sw-input-disabled"
59+
: (error) ? "sw-input-error"
60+
: "sw-input";
61+
return (
62+
<SWModal className="p-12 z-10 w-1/2" setIsShown={setModalIsShown}>
63+
<form onSubmit={onSubmit} className={`p-24 flex w-full items-center justify-between gap-6 border ${inputStyle}`}>
64+
<label className="w-fit sw-fw-1 rgb-1">{title}:</label>
65+
<input className="flex grow" ref={inputRef} onChange={() => setError("")} disabled={isLoading} />
66+
<button className={`sw-btn w-fit`} type="submit">
67+
{ isLoading ? <SWLoadingIcon className="w-4"/> : <FaChevronRight className="w-4 h-4"/> }
68+
</button>
69+
</form>
70+
<div className="h-12 mt-3 rgb-alert sw-fw-1">
71+
<label>{error}</label>
72+
</div>
73+
</SWModal>
74+
);
75+
}
76+
77+
export default SWModalInputBar;

solid-watchparty/src/components/SWNavbar.jsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,12 @@ function SWNavbar()
3434
return (
3535
<div className="w-full flex p-8 grow-0">
3636
<div className="flex items-center basis-1/3">
37-
<label className="sw-fw-1 text-left sw-text-gradient">solid-watchparty</label>
37+
<label className="sw-fw-1 text-left">solid-watchparty-v0</label>
3838
</div>
39-
<div className="flex sw-fw-1 basis-1/3 justify-center items-center">
40-
<p>Solid Watchparty</p>
39+
<div className="flex justify-center basis-1/3">
40+
<p className="flex sw-fw-1 justify-center items-center sw-text-gradient">
41+
solid-watchparty
42+
</p>
4143
</div>
4244
<div className="flex items-center basis-1/3 justify-end">
4345
<div className="flex gap-4 items-center sw-fw-1">

0 commit comments

Comments
 (0)