diff --git a/app/web/src/components/pages/SettingsAdminBody.tsx b/app/web/src/components/pages/SettingsAdminBody.tsx
index d071576..321debf 100644
--- a/app/web/src/components/pages/SettingsAdminBody.tsx
+++ b/app/web/src/components/pages/SettingsAdminBody.tsx
@@ -11,6 +11,11 @@ function Inner(props: { locale: Locale }) {
const isAdmin = me.data?.user?.role === "admin";
const openNet = trpc.settings.getOpenNetwork.useQuery(undefined, { enabled: isAdmin });
const saveOpenNet = trpc.settings.saveOpenNetwork.useMutation();
+ const ddpStatus = trpc.settings.dandanplayAuthStatus.useQuery(undefined, { enabled: isAdmin });
+ const ddpLogin = trpc.settings.loginDandanplay.useMutation();
+ const ddpLogout = trpc.settings.logoutDandanplay.useMutation();
+ const [ddpUser, setDdpUser] = useState("");
+ const [ddpPass, setDdpPass] = useState("");
const [appId, setAppId] = useState("");
const [appSecret, setAppSecret] = useState("");
@@ -101,6 +106,85 @@ function Inner(props: { locale: Locale }) {
{t(locale, "settings.save")}
+
+
+
{label("settings.ddpLogin")}
+
{label("settings.ddpLoginHint")}
+ {ddpStatus.data?.loggedIn ? (
+
+
+ {t(locale, "settings.ddpLoggedInAs", {
+ name: ddpStatus.data.screenName ?? "",
+ })}
+
+
+
+ ) : (
+
+ setDdpUser(e.target.value)}
+ autoComplete="username"
+ />
+ setDdpPass(e.target.value)}
+ autoComplete="current-password"
+ />
+
+
+ )}
+
);
}
diff --git a/packages/danmaku/src/client.ts b/packages/danmaku/src/client.ts
index 77d2aa1..0dfe056 100644
--- a/packages/danmaku/src/client.ts
+++ b/packages/danmaku/src/client.ts
@@ -197,3 +197,62 @@ export async function openAnimeEpisodes(animeId: number): Promise