Skip to content

Commit 2888dea

Browse files
authored
release 4/14 (#695)
* PWA Manifest * レコメンドロジックの変更
2 parents 83214a6 + 900f011 commit 2888dea

File tree

17 files changed

+210
-92
lines changed

17 files changed

+210
-92
lines changed

bun.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@
430430

431431
"@types/body-parser": ["@types/[email protected]", "", { "dependencies": { "@types/connect": "*", "@types/node": "*" } }, "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg=="],
432432

433-
"@types/bun": ["@types/[email protected].4", "", { "dependencies": { "bun-types": "1.2.4" } }, "sha512-QtuV5OMR8/rdKJs213iwXDpfVvnskPXY/S0ZiFbsTjQZycuqPbMW8Gf/XhLfwE5njW8sxI2WjISURXPlHypMFA=="],
433+
"@types/bun": ["@types/[email protected].9", "", { "dependencies": { "bun-types": "1.2.9" } }, "sha512-epShhLGQYc4Bv/aceHbmBhOz1XgUnuTZgcxjxk+WXwNyDXavv5QHD1QEFV0FwbTSQtNq6g4ZcV6y0vZakTjswg=="],
434434

435435
"@types/caseless": ["@types/[email protected]", "", {}, "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg=="],
436436

@@ -536,7 +536,7 @@
536536

537537
"buffer-equal-constant-time": ["[email protected]", "", {}, "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="],
538538

539-
"bun-types": ["[email protected].4", "", { "dependencies": { "@types/node": "*", "@types/ws": "~8.5.10" } }, "sha512-nDPymR207ZZEoWD4AavvEaa/KZe/qlrbMSchqpQwovPZCKc7pwMoENjEtHgMKaAjJhy+x6vfqSBA1QU3bJgs0Q=="],
539+
"bun-types": ["[email protected].9", "", { "dependencies": { "@types/node": "*", "@types/ws": "*" } }, "sha512-dk/kOEfQbajENN/D6FyiSgOKEuUi9PWfqKQJEgwKrCMWbjS/S6tEXp178mWvWAcUSYm9ArDlWHZKO3T/4cLXiw=="],
540540

541541
"busboy": ["[email protected]", "", { "dependencies": { "streamsearch": "^1.1.0" } }, "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA=="],
542542

common/lib/panic.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// unexpected error
22
export function panic(reason: string): never {
3-
throw new Error(reason, {
4-
cause: "panic",
5-
});
3+
throw new Error(reason);
4+
// TODO: 型エラーとなるため一時的にコメントアウト
5+
// throw new Error(reason, {
6+
// cause: "panic",
7+
// });
68
}

server/prisma/sql/recommend.sql

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,33 @@
11
-- $1 = senderId
22
SELECT
3-
*,
3+
recv.id,
4+
recv.name,
5+
recv.gender,
6+
recv.grade,
7+
recv.faculty,
8+
recv.department,
9+
recv.intro,
10+
recv."guid",
11+
recv."pictureUrl",
12+
json_agg(DISTINCT jsonb_build_object(
13+
'id', c.id,
14+
'name', c.name,
15+
'teacher', c.teacher,
16+
'slots', (
17+
SELECT json_agg(
18+
jsonb_build_object(
19+
'courseId', "Slot"."courseId",
20+
'day', "Slot"."day",
21+
'period', "Slot"."period"
22+
)
23+
) FROM "Slot" WHERE "Slot"."courseId" = c.id)
24+
)
25+
) FILTER (WHERE c.id IS NOT NULL) AS "courses",
26+
json_agg(DISTINCT jsonb_build_object(
27+
'id', s.id,
28+
'name', s.name,
29+
'group', s.group
30+
)) FILTER (WHERE s.id IS NOT NULL) AS "interestSubjects",
431
-- course overlap
532
(SELECT COUNT(1) FROM "Course" course
633
WHERE EXISTS (SELECT 1 FROM "Enrollment" e WHERE e."courseId" = course.id AND e."userId" = recv.id)
@@ -12,6 +39,13 @@ SELECT
1239
AND EXISTS (SELECT 1 FROM "Interest" i WHERE i."subjectId" = subj.id AND i."userId" = $1)
1340
) AS overlap
1441
FROM "User" recv
42+
43+
LEFT JOIN "Enrollment" ON "Enrollment"."userId" = recv.id
44+
LEFT JOIN "Course" c on c.id = "Enrollment"."courseId"
45+
LEFT JOIN "Slot" ON "Slot"."courseId" = c.id
46+
LEFT JOIN "Interest" ON "Interest"."userId" = recv.id
47+
LEFT JOIN "InterestSubject" s ON s.id = "Interest"."subjectId"
48+
1549
WHERE recv.id <> $1
1650

1751
AND NOT EXISTS (
@@ -26,5 +60,20 @@ AND NOT EXISTS (
2660
AND status = 'PENDING'
2761
)
2862

63+
-- 授業の登録も興味分野の登録も 0 件のユーザは除外
64+
AND (
65+
EXISTS (
66+
SELECT 1 FROM "Enrollment" e
67+
WHERE e."userId" = recv.id
68+
)
69+
OR
70+
EXISTS (
71+
SELECT 1 FROM "Interest" i
72+
WHERE i."userId" = recv.id
73+
)
74+
)
75+
76+
GROUP BY recv.id
77+
2978
ORDER BY overlap DESC
3079
LIMIT $2 OFFSET $3;
Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import { recommend } from "@prisma/client/sql";
2-
import type { UserID, UserWithCoursesAndSubjects } from "common/types";
2+
import type {
3+
Course,
4+
InterestSubject,
5+
UserID,
6+
UserWithCoursesAndSubjects,
7+
} from "common/types";
38
import { prisma } from "../../database/client";
4-
import { getCoursesByUserId } from "../../database/courses";
5-
import * as interest from "../../database/interest";
6-
import { getUserByID } from "../../database/users";
79

810
export async function recommendedTo(
911
user: UserID,
@@ -15,23 +17,17 @@ export async function recommendedTo(
1517
count: number;
1618
}>
1719
> {
18-
const result = await prisma.$queryRawTyped(recommend(user, limit, offset));
19-
return Promise.all(
20-
result.map(async (res) => {
21-
const { overlap: count, ...u } = res;
22-
if (count === null) throw new Error("count is null: something is wrong");
23-
// TODO: user の情報はここで再度 DB に問い合わせるのではなく、 recommend の sql で取得
24-
const user = await getUserByID(u.id);
25-
const courses = getCoursesByUserId(u.id);
26-
const subjects = interest.of(u.id);
27-
return {
28-
count: Number(count),
29-
u: {
30-
...user,
31-
courses: await courses,
32-
interestSubjects: await subjects,
33-
},
34-
};
35-
}),
36-
);
20+
const users = await prisma.$queryRawTyped(recommend(user, limit, offset));
21+
console.log("🚀", users);
22+
return users.map((user) => {
23+
const { overlap: count, ...u } = user;
24+
return {
25+
count: Number(count),
26+
u: {
27+
...u,
28+
interestSubjects: (u.interestSubjects ?? []) as InterestSubject[], // TODO: type
29+
courses: (u.courses ?? []) as Course[], // TODO: type
30+
},
31+
};
32+
});
3733
}

web/app/chat/layout.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ export default function Layout({ children }: { children: React.ReactNode }) {
99
<ModalProvider>
1010
<Header title="チャット" />
1111
<NavigateByAuthState type="toLoginForUnauthenticated">
12-
<div className="h-full overflow-y-auto pt-12 pb-12">{children}</div>
12+
<div className="cm-pb-footer h-full overflow-y-auto pt-12">
13+
{children}
14+
</div>
1315
</NavigateByAuthState>
1416
<BottomBar activeTab="3_chat" />
1517
</ModalProvider>

web/app/friends/layout.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ export default function Layout({ children }: { children: React.ReactNode }) {
99
<ModalProvider>
1010
<Header title="フレンド" />
1111
<NavigateByAuthState type="toLoginForUnauthenticated">
12-
<div className="h-full overflow-y-auto pt-12 pb-12">{children}</div>
12+
<div className="cm-pb-footer h-full overflow-y-auto pt-12">
13+
{children}
14+
</div>
1315
</NavigateByAuthState>
1416
<BottomBar activeTab="1_friends" />
1517
</ModalProvider>

web/app/globals.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,8 @@
1111
.cm-li-btn {
1212
@apply no-animation h-auto w-full justify-start rounded-none border-none bg-white px-6 py-4 text-left font-normal text-base shadow-none hover:bg-zinc-100 focus:bg-zinc-300;
1313
}
14+
15+
/* Bottom Bar の分の幅 */
16+
.cm-pb-footer {
17+
padding-bottom: calc(3rem + env(safe-area-inset-bottom));
18+
}

web/app/home/layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export default function Layout({
1111
<>
1212
<Header />
1313
<NavigateByAuthState type="toLoginForUnauthenticated">
14-
<div className="h-full pt-12 pb-12">{children}</div>
14+
<div className="cm-pb-footer h-full pt-12">{children}</div>
1515
</NavigateByAuthState>
1616
<BottomBar activeTab="0_home" />
1717
</>

web/app/layout.tsx

Lines changed: 15 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,30 @@
1-
"use client";
2-
3-
import { CssBaseline, ThemeProvider, createTheme } from "@mui/material";
4-
import { SnackbarProvider } from "notistack";
5-
import React from "react";
1+
import type React from "react";
62
import "./globals.css";
73
import "@fontsource/roboto/300.css";
84
import "@fontsource/roboto/400.css";
95
import "@fontsource/roboto/500.css";
106
import "@fontsource/roboto/700.css";
11-
import BanLandscape from "~/components/BanLandscape";
12-
import SSEProvider from "~/components/SSEProvider";
13-
import { AlertProvider } from "~/components/common/alert/AlertProvider";
7+
import type { Metadata, Viewport } from "next";
8+
import Providers from "~/components/Providers";
9+
10+
export const viewport: Viewport = {
11+
width: "device-width",
12+
initialScale: 1,
13+
viewportFit: "cover",
14+
};
1415

15-
const theme = createTheme({
16-
palette: {
17-
primary: {
18-
main: "#039BE5",
19-
},
20-
secondary: {
21-
main: "#E9F8FF",
22-
},
23-
},
24-
});
16+
export const metadata: Metadata = {
17+
title: "CourseMate (β版)",
18+
description: "同じ授業の人と友達になろう",
19+
};
2520

2621
export default function RootLayout({
2722
children,
28-
}: {
29-
children: React.ReactNode;
30-
}) {
23+
}: { children: React.ReactNode }) {
3124
return (
3225
<html lang="en" className="h-full">
33-
<head>
34-
<meta charSet="UTF-8" />
35-
<link rel="icon" type="image/svg+xml" href="/course-mate-icon.svg" />
36-
<meta
37-
name="viewport"
38-
content="width=device-width, initial-scale=1.0, maximum-scale=1.0"
39-
/>
40-
<title>CourseMate</title>
41-
</head>
4226
<body className="h-full">
43-
<ThemeProvider theme={theme}>
44-
<CssBaseline />
45-
<SnackbarProvider
46-
autoHideDuration={2000}
47-
anchorOrigin={{ horizontal: "right", vertical: "top" }}
48-
>
49-
<React.StrictMode>
50-
<CssBaseline />
51-
<AlertProvider>
52-
{/* <ModalProvider> */}
53-
<BanLandscape />
54-
<SSEProvider>{children}</SSEProvider>
55-
{/* </ModalProvider> */}
56-
</AlertProvider>
57-
</React.StrictMode>
58-
</SnackbarProvider>
59-
</ThemeProvider>
27+
<Providers>{children}</Providers>
6028
</body>
6129
</html>
6230
);

web/app/manifest.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import type { MetadataRoute } from "next";
2+
3+
export default function manifest(): MetadataRoute.Manifest {
4+
return {
5+
name: "CourseMate",
6+
short_name: "CourseMate",
7+
description: "同じ授業を履修している友達を見つけられるアプリ",
8+
start_url: "/",
9+
display: "standalone",
10+
background_color: "#ffffff",
11+
theme_color: "#ffffff",
12+
icons: [
13+
{
14+
src: "/icon-192x192.png",
15+
sizes: "192x192",
16+
type: "image/png",
17+
},
18+
{
19+
src: "/icon-512x512.png",
20+
sizes: "512x512",
21+
type: "image/png",
22+
},
23+
],
24+
};
25+
}

0 commit comments

Comments
 (0)