Skip to content

Commit 3ac4992

Browse files
committed
merge main
2 parents 04fa09d + cf3e6f2 commit 3ac4992

File tree

29 files changed

+579
-128
lines changed

29 files changed

+579
-128
lines changed

.github/workflows/rust.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@ jobs:
2222
~/.rustup/
2323
scraper/target
2424
key: cargo-cache-${{ github.job }}-${{ runner.os }}-${{ hashFiles('**/Cargo.lock') }}
25-
- uses: actions-rust-lang/setup-rust-toolchain@v1
25+
- uses: dtolnay/rust-toolchain@v1
2626
with:
27+
toolchain: 1.82.0
2728
components: clippy,rustfmt
2829
- run: cargo build
2930
- run: cargo build --release

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ dev-db:
6969
-e POSTGRES_DB=database \
7070
postgres:alpine
7171
@echo "Waiting for PostgreSQL to be ready..."
72-
@sleep 5 # PostgreSQLが起動するまでの待機(必要に応じて調整)
72+
@sleep 2 # PostgreSQLが起動するまでの待機(必要に応じて調整)
7373
@until docker exec postgres pg_isready -U user -d database; do \
7474
echo "Waiting for PostgreSQL to be ready..."; \
7575
sleep 1; \
@@ -78,7 +78,7 @@ dev-db:
7878
@cd server; if command -v prisma; then \
7979
prisma generate; prisma db push; else \
8080
bunx prisma generate; bunx prisma db push; fi
81-
@make seed;
81+
@make seed
8282
@echo "Seeding completed."
8383

8484
# Sync (install/update packages, generate prisma, etc)

common/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export type {
77
Gender,
88
RelationshipStatus,
99
InterestSubject,
10+
Interest,
1011
User,
1112
InitUser,
1213
UpdateUser,
@@ -17,6 +18,7 @@ export type {
1718
Course,
1819
Enrollment,
1920
Day,
21+
UserWithCoursesAndSubjects,
2022
MessageID,
2123
ShareRoomID,
2224
Message,

common/zod/schemas.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ export const InterestSubjectSchema = z.object({
3838
group: z.string(),
3939
});
4040

41+
export const InterestSchema = z.object({
42+
userId: UserIDSchema,
43+
subjectId: z.number(),
44+
});
45+
4146
export const UserSchema = z.object({
4247
id: UserIDSchema,
4348
guid: GUIDSchema,
@@ -103,6 +108,11 @@ export const EnrollmentSchema = z.object({
103108
courseId: CourseIDSchema,
104109
});
105110

111+
export const UserWithCoursesAndSubjectsSchema = UserSchema.extend({
112+
courses: CourseSchema.array(),
113+
interestSubjects: InterestSubjectSchema.array(),
114+
});
115+
106116
export const MessageIDSchema = z.number(); // TODO! Add __internal_prevent_cast_MessageID: PhantomData
107117
export const ShareRoomIDSchema = z.number();
108118

@@ -137,6 +147,7 @@ export const DMOverviewSchema = z.object({
137147
name: NameSchema,
138148
thumbnail: z.string(),
139149
lastMsg: MessageSchema.optional(),
150+
unreadMessages: z.number(),
140151
});
141152

142153
export const SharedRoomOverviewSchema = z.object({

common/zod/types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import type {
1414
InitRoomSchema,
1515
InitSharedRoomSchema,
1616
InitUserSchema,
17+
InterestSchema,
1718
InterestSubjectSchema,
1819
IntroLongSchema,
1920
IntroShortSchema,
@@ -37,6 +38,7 @@ import type {
3738
UpdateUserSchema,
3839
UserIDSchema,
3940
UserSchema,
41+
UserWithCoursesAndSubjectsSchema,
4042
} from "./schemas";
4143

4244
export type UserID = z.infer<typeof UserIDSchema>;
@@ -47,6 +49,7 @@ export type PictureUrl = z.infer<typeof PictureUrlSchema>;
4749
export type Gender = z.infer<typeof GenderSchema>;
4850
export type RelationshipStatus = z.infer<typeof RelationshipStatusSchema>;
4951
export type InterestSubject = z.infer<typeof InterestSubjectSchema>;
52+
export type Interest = z.infer<typeof InterestSchema>;
5053
export type User = z.infer<typeof UserSchema>;
5154
export type InitUser = z.infer<typeof InitUserSchema>;
5255
export type UpdateUser = z.infer<typeof UpdateUserSchema>;
@@ -59,6 +62,9 @@ export type Course = z.infer<typeof CourseSchema>;
5962
export type Enrollment = z.infer<typeof EnrollmentSchema>;
6063
export type Day = z.infer<typeof DaySchema>;
6164
export type Period = z.infer<typeof PeriodSchema>;
65+
export type UserWithCoursesAndSubjects = z.infer<
66+
typeof UserWithCoursesAndSubjectsSchema
67+
>;
6268
export type MessageID = z.infer<typeof MessageIDSchema>;
6369
export type ShareRoomID = z.infer<typeof ShareRoomIDSchema>;
6470
export type Message = z.infer<typeof MessageSchema>;

flake.nix

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
biome
2828
pkg-config
2929
openssl
30-
pkgs.prisma
30+
lefthook
31+
# pkgs.prisma
3132
] ++ [
3233
rust-pkgs
3334
];

server/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,6 @@
3636
"globals": "^15.8.0",
3737
"prisma": "^5.11.0",
3838
"typescript": "^5.4.5"
39-
}
39+
},
40+
"trustedPackages": ["prisma"]
4041
}

server/prisma/schema.prisma

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,9 @@ model InterestSubject {
5757
id Int @id @default(autoincrement())
5858
name String
5959
group String // such as Computer Science | name = ML
60+
Interest Interest[] // ignore this
6061
6162
@@unique([name, group])
62-
Interest Interest[] // ignore this
6363
}
6464

6565
// User->Interest->InterestSubject
@@ -142,6 +142,7 @@ model Message {
142142
edited Boolean @default(false)
143143
content String
144144
isPicture Boolean // iff the message is a picture. if true, then content is a url of picture.
145+
read Boolean
145146
relation Relationship? @relation(fields: [relationId], references: [id], onDelete: Cascade)
146147
relationId Int?
147148
sharedRoom SharedRoom? @relation(fields: [sharedRoomId], references: [id], onDelete: Cascade)

server/src/database/chat.ts

Lines changed: 87 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
getPendingRequestsFromUser,
2020
getPendingRequestsToUser,
2121
} from "./requests";
22+
import { getUserByID } from "./users";
2223

2324
export async function getOverview(
2425
user: UserID,
@@ -35,59 +36,17 @@ export async function getOverview(
3536

3637
//マッチングしている人のオーバービュー
3738
const matchingOverview = await Promise.all(
38-
matched.value.map(async (friend) => {
39-
const lastMessageResult = await getLastMessage(user, friend.id);
40-
const lastMessage = lastMessageResult.ok
41-
? lastMessageResult.value
42-
: undefined;
43-
const overview: DMOverview = {
44-
isDM: true,
45-
matchingStatus: "matched",
46-
friendId: friend.id,
47-
name: friend.name,
48-
thumbnail: friend.pictureUrl,
49-
lastMsg: lastMessage,
50-
};
51-
return overview;
52-
}),
39+
matched.value.map(async (m) => getOverviewBetween(user, m.id)),
5340
);
5441

5542
//自分にリクエストを送ってきた人のオーバービュー
5643
const senderOverview = await Promise.all(
57-
senders.value.map(async (sender) => {
58-
const lastMessageResult = await getLastMessage(user, sender.id);
59-
const lastMessage = lastMessageResult.ok
60-
? lastMessageResult.value
61-
: undefined;
62-
const overview: DMOverview = {
63-
isDM: true,
64-
matchingStatus: "otherRequest",
65-
friendId: sender.id,
66-
name: sender.name,
67-
thumbnail: sender.pictureUrl,
68-
lastMsg: lastMessage,
69-
};
70-
return overview;
71-
}),
44+
senders.value.map((s) => getOverviewBetween(user, s.id)),
7245
);
7346

7447
//自分がリクエストを送った人のオーバービュー
7548
const receiverOverview = await Promise.all(
76-
receivers.value.map(async (receiver) => {
77-
const lastMessageResult = await getLastMessage(user, receiver.id);
78-
const lastMessage = lastMessageResult.ok
79-
? lastMessageResult.value
80-
: undefined;
81-
const overview: DMOverview = {
82-
isDM: true,
83-
matchingStatus: "myRequest",
84-
friendId: receiver.id,
85-
name: receiver.name,
86-
thumbnail: receiver.pictureUrl,
87-
lastMsg: lastMessage,
88-
};
89-
return overview;
90-
}),
49+
receivers.value.map((r) => getOverviewBetween(user, r.id)),
9150
);
9251

9352
const sharedRooms: {
@@ -130,6 +89,67 @@ export async function getOverview(
13089
}
13190
}
13291

92+
async function getOverviewBetween(
93+
user: number,
94+
other: number,
95+
): Promise<DMOverview> {
96+
const relR = await getRelation(user, other);
97+
if (!relR.ok) throw relR.error;
98+
const rel = relR.value;
99+
100+
const friendId =
101+
rel.receivingUserId === user ? rel.sendingUserId : rel.receivingUserId;
102+
const lastMessage = getLastMessage(user, friendId).then((val) => {
103+
if (val.ok) return val.value;
104+
return undefined;
105+
});
106+
const unreadCount = unreadMessages(user, rel.id).then((val) => {
107+
if (val.ok) return val.value;
108+
throw val.error;
109+
});
110+
const friend = await getUserByID(friendId).then((val) => {
111+
if (val.ok) return val.value;
112+
throw val.error;
113+
});
114+
const overview: DMOverview = {
115+
isDM: true,
116+
matchingStatus: "matched",
117+
friendId: friendId,
118+
name: friend.name,
119+
thumbnail: friend.pictureUrl,
120+
lastMsg: await lastMessage,
121+
unreadMessages: await unreadCount,
122+
};
123+
return overview;
124+
}
125+
export async function markAsRead(
126+
rel: RelationshipID,
127+
reader: UserID,
128+
message: MessageID,
129+
) {
130+
const val = {
131+
readerId: reader,
132+
messageId: message,
133+
relationId: rel,
134+
};
135+
return await prisma.message.updateMany({
136+
where: {
137+
id: {
138+
lte: message,
139+
},
140+
relationId: rel,
141+
creator: {
142+
not: {
143+
equals: reader,
144+
},
145+
},
146+
},
147+
data: {
148+
read: true,
149+
},
150+
});
151+
}
152+
133153
/**
134154
* DM の送信
135155
* 送信者の id は呼び出す側で指定すること
@@ -143,6 +163,7 @@ export async function sendDM(
143163
data: {
144164
relationId: relation,
145165
isPicture: false,
166+
read: false,
146167
...content,
147168
},
148169
});
@@ -393,3 +414,24 @@ export async function getLastMessage(
393414
return Err(e);
394415
}
395416
}
417+
418+
// only works on Relationship (= DM) for now.
419+
export async function unreadMessages(userId: UserID, roomId: RelationshipID) {
420+
try {
421+
// FIXME: this makes request twice to the database. it's not efficient.
422+
const unreadMessages = await prisma.message.count({
423+
where: {
424+
read: false,
425+
relationId: roomId,
426+
creator: {
427+
not: {
428+
equals: userId,
429+
},
430+
},
431+
},
432+
});
433+
return Ok(unreadMessages);
434+
} catch (e) {
435+
return Err(e);
436+
}
437+
}

server/src/database/matches.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export async function getRelation(
88
u2: UserID,
99
): Promise<Result<Relationship>> {
1010
try {
11-
// TODO!!!! FIXME!!!!!! FIX THIS findMany!!!!!
11+
// FIXME: fix this findMany
1212
const rel = await prisma.relationship.findMany({
1313
where: {
1414
OR: [

0 commit comments

Comments
 (0)