show febbox usage

This commit is contained in:
Pas 2025-12-19 15:58:54 -07:00
parent 28527618a9
commit 4f6e56fd22
3 changed files with 58 additions and 9 deletions

View file

@ -1276,8 +1276,7 @@
"2": "2. Open DevTools or inspect the page",
"3": "3. Go to Application tab → Cookies",
"4": "4. Copy the 'ui' cookie's value.",
"5": "5. Close the tab, but do NOT logout!",
"warning": "(Do not share this token!)"
"5": "5. Close the tab, but do NOT logout!"
},
"tokenLabel": "Token",
"tokenExample": {
@ -1286,7 +1285,9 @@
"description": "This is what a Febbox UI token looks like:",
"warning": "Don't try to use, it's fake.",
"close": "Got it"
}
},
"traffic": "{{used}} / {{limit}} High-speed Traffic • Resets in {{reset}}",
"trafficExplanation": "Febbox gives you 100GB/month of high-speed traffic, the streams might buffer more after you've used up your quota. Depends on your internet speed and the quality of the stream."
},
"status": {
"success": "success",

View file

@ -24,6 +24,7 @@ import { Heading1, Heading2, Paragraph } from "@/components/utils/Text";
import {
SetupPart,
Status,
fetchFebboxQuota,
testFebboxKey,
testTorboxToken,
testdebridToken,
@ -237,9 +238,10 @@ function BackendEdit({ backendUrl, setBackendUrl }: BackendEditProps) {
async function getFebboxKeyStatus(febboxKey: string | null) {
if (febboxKey) {
const status: Status = await testFebboxKey(febboxKey);
return status;
const quota = await fetchFebboxQuota(febboxKey);
return { status, quota };
}
return "unset";
return { status: "unset" as Status, quota: null };
}
interface FebboxSetupProps extends FebboxKeyProps {
@ -282,6 +284,7 @@ export function FebboxSetup({
}, [user.account, febboxKey, preferences.febboxKey, setFebboxKey, mode]);
const [status, setStatus] = useState<Status>("unset");
const [quota, setQuota] = useState<any>(null);
const statusMap: Record<Status, StatusCircleProps["type"]> = {
error: "error",
success: "success",
@ -293,7 +296,8 @@ export function FebboxSetup({
useEffect(() => {
const checkTokenStatus = async () => {
const result = await getFebboxKeyStatus(febboxKey);
setStatus(result);
setStatus(result.status);
setQuota(result.quota);
};
checkTokenStatus();
}, [febboxKey]);
@ -395,9 +399,6 @@ export function FebboxSetup({
<br />
<Trans i18nKey="fedapi.setup.step.5" />
</p>
<p className="text-type-danger mt-2">
<Trans i18nKey="fedapi.setup.step.warning" />
</p>
</div>
<Divider marginClass="my-6 px-8 box-content -mx-8" />
@ -438,6 +439,26 @@ export function FebboxSetup({
{t("fedapi.status.invalid_token")}
</p>
)}
{status === "success" &&
quota &&
(() => {
if (!quota?.data?.flow) return null;
const {
traffic_usage: used,
traffic_limit: limit,
reset_at: reset,
} = quota.data.flow;
return (
<>
<p className="text-sm text-green-500 mt-2">
{t("fedapi.setup.traffic", { used, limit, reset })}
</p>
<p className="max-w-[30rem] text-xs opacity-70 mt-2">
{t("fedapi.setup.trafficExplanation")}
</p>
</>
);
})()}
</>
) : null}
</SettingsCard>

View file

@ -58,6 +58,33 @@ function testProxy(url: string) {
});
}
export async function fetchFebboxQuota(febboxKey: string | null): Promise<any> {
if (!febboxKey) {
return null;
}
console.log("SetupPart.tsx: Fetching Febbox quota");
try {
const response = await fetch("https://fed-api.pstream.mov/quota", {
headers: {
"ui-token": febboxKey,
},
});
if (!response.ok) {
console.error("Febbox quota API failed with status:", response.status);
return null;
}
const data = await response.json();
console.log("SetupPart.tsx: Febbox quota fetched successfully");
return data;
} catch (error) {
console.error("SetupPart.tsx: Error fetching Febbox quota:", error);
return null;
}
}
export async function testFebboxKey(febboxKey: string | null): Promise<Status> {
const febboxApiTestUrl = `https://fed-api.pstream.mov/movie/tt0325980`;