mirror of
https://github.com/movie-web/movie-web.git
synced 2024-11-13 09:45:07 +01:00
commit
dd56986081
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "movie-web",
|
"name": "movie-web",
|
||||||
"version": "4.1.0",
|
"version": "4.1.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"homepage": "https://movie-web.app",
|
"homepage": "https://movie-web.app",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
},
|
},
|
||||||
"generate": {
|
"generate": {
|
||||||
"title": "Your passphrase",
|
"title": "Your passphrase",
|
||||||
|
"passphraseFrameLabel": "Passphrase",
|
||||||
"next": "I have saved my passphrase",
|
"next": "I have saved my passphrase",
|
||||||
"description": "Your passphrase acts as your username and password. Make sure to keep it safe as you will need to enter it to login to your account"
|
"description": "Your passphrase acts as your username and password. Make sure to keep it safe as you will need to enter it to login to your account"
|
||||||
},
|
},
|
||||||
|
@ -9,6 +9,7 @@ import { PlayerMeta } from "@/stores/player/slices/source";
|
|||||||
// for anybody who cares - these are anonymous metrics.
|
// for anybody who cares - these are anonymous metrics.
|
||||||
// They are just used for figuring out if providers are broken or not
|
// They are just used for figuring out if providers are broken or not
|
||||||
const metricsEndpoint = "https://backend.movie-web.app/metrics/providers";
|
const metricsEndpoint = "https://backend.movie-web.app/metrics/providers";
|
||||||
|
const captchaMetricsEndpoint = "https://backend.movie-web.app/metrics/captcha";
|
||||||
const batchId = () => nanoid(32);
|
const batchId = () => nanoid(32);
|
||||||
|
|
||||||
export type ProviderMetric = {
|
export type ProviderMetric = {
|
||||||
@ -136,8 +137,17 @@ export function scrapePartsToProviderMetric(
|
|||||||
export function useReportProviders() {
|
export function useReportProviders() {
|
||||||
const report = useCallback((items: ProviderMetric[]) => {
|
const report = useCallback((items: ProviderMetric[]) => {
|
||||||
if (items.length === 0) return;
|
if (items.length === 0) return;
|
||||||
reportProviders(items);
|
reportProviders(items).catch(() => {});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return { report };
|
return { report };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function reportCaptchaSolve(success: boolean) {
|
||||||
|
ofetch(captchaMetricsEndpoint, {
|
||||||
|
method: "POST",
|
||||||
|
body: {
|
||||||
|
success,
|
||||||
|
},
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
|
@ -25,7 +25,9 @@ export function PassphraseDisplay(props: { mnemonic: string }) {
|
|||||||
return (
|
return (
|
||||||
<div className="rounded-lg border border-authentication-border/50 ">
|
<div className="rounded-lg border border-authentication-border/50 ">
|
||||||
<div className="px-4 py-2 flex justify-between border-b border-authentication-border/50">
|
<div className="px-4 py-2 flex justify-between border-b border-authentication-border/50">
|
||||||
<p className="font-bold text-sm text-white">Passphrase</p>
|
<p className="font-bold text-sm text-white">
|
||||||
|
{t("auth.generate.passphraseFrameLabel")}
|
||||||
|
</p>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="text-authentication-copyText hover:text-authentication-copyTextHover transition-colors flex gap-2 items-center cursor-pointer"
|
className="text-authentication-copyText hover:text-authentication-copyTextHover transition-colors flex gap-2 items-center cursor-pointer"
|
||||||
|
@ -24,7 +24,9 @@ export function useAuthData() {
|
|||||||
const clearProgress = useProgressStore((s) => s.clear);
|
const clearProgress = useProgressStore((s) => s.clear);
|
||||||
const setTheme = useThemeStore((s) => s.setTheme);
|
const setTheme = useThemeStore((s) => s.setTheme);
|
||||||
const setAppLanguage = useLanguageStore((s) => s.setLanguage);
|
const setAppLanguage = useLanguageStore((s) => s.setLanguage);
|
||||||
const setCaptionLanguage = useSubtitleStore((s) => s.setLanguage);
|
const importSubtitleLanguage = useSubtitleStore(
|
||||||
|
(s) => s.importSubtitleLanguage
|
||||||
|
);
|
||||||
|
|
||||||
const replaceBookmarks = useBookmarkStore((s) => s.replaceBookmarks);
|
const replaceBookmarks = useBookmarkStore((s) => s.replaceBookmarks);
|
||||||
const replaceItems = useProgressStore((s) => s.replaceItems);
|
const replaceItems = useProgressStore((s) => s.replaceItems);
|
||||||
@ -72,7 +74,7 @@ export function useAuthData() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (settings.defaultSubtitleLanguage) {
|
if (settings.defaultSubtitleLanguage) {
|
||||||
setCaptionLanguage(settings.defaultSubtitleLanguage);
|
importSubtitleLanguage(settings.defaultSubtitleLanguage);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (settings.applicationTheme) {
|
if (settings.applicationTheme) {
|
||||||
@ -83,7 +85,7 @@ export function useAuthData() {
|
|||||||
replaceBookmarks,
|
replaceBookmarks,
|
||||||
replaceItems,
|
replaceItems,
|
||||||
setAppLanguage,
|
setAppLanguage,
|
||||||
setCaptionLanguage,
|
importSubtitleLanguage,
|
||||||
setTheme,
|
setTheme,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
@ -24,7 +24,7 @@ export function useDerived<T>(
|
|||||||
const setter = useCallback<Dispatch<SetStateAction<T>>>(
|
const setter = useCallback<Dispatch<SetStateAction<T>>>(
|
||||||
(inp) => {
|
(inp) => {
|
||||||
if (!(inp instanceof Function)) setOverwrite(inp);
|
if (!(inp instanceof Function)) setOverwrite(inp);
|
||||||
else setOverwrite((s) => inp(s ?? initial));
|
else setOverwrite((s) => inp(s !== undefined ? s : initial));
|
||||||
},
|
},
|
||||||
[initial, setOverwrite]
|
[initial, setOverwrite]
|
||||||
);
|
);
|
||||||
|
@ -196,7 +196,7 @@ export function SettingsPage() {
|
|||||||
<SettingsLayout>
|
<SettingsLayout>
|
||||||
<div id="settings-account">
|
<div id="settings-account">
|
||||||
<Heading1 border className="!mb-0">
|
<Heading1 border className="!mb-0">
|
||||||
Account
|
{t("settings.account.title")}
|
||||||
</Heading1>
|
</Heading1>
|
||||||
{user.account && state.profile.state ? (
|
{user.account && state.profile.state ? (
|
||||||
<AccountSettings
|
<AccountSettings
|
||||||
|
@ -122,7 +122,7 @@ export function SidebarPart() {
|
|||||||
boundaryElement=".sidebar-boundary"
|
boundaryElement=".sidebar-boundary"
|
||||||
>
|
>
|
||||||
<div className="hidden lg:block">
|
<div className="hidden lg:block">
|
||||||
<SidebarSection title="Settings">
|
<SidebarSection title={t("global.pages.settings")}>
|
||||||
{settingLinks.map((v) => (
|
{settingLinks.map((v) => (
|
||||||
<SidebarLink
|
<SidebarLink
|
||||||
icon={v.icon}
|
icon={v.icon}
|
||||||
|
@ -2,6 +2,7 @@ import Turnstile, { BoundTurnstileObject } from "react-turnstile";
|
|||||||
import { create } from "zustand";
|
import { create } from "zustand";
|
||||||
import { immer } from "zustand/middleware/immer";
|
import { immer } from "zustand/middleware/immer";
|
||||||
|
|
||||||
|
import { reportCaptchaSolve } from "@/backend/helpers/report";
|
||||||
import { conf } from "@/setup/config";
|
import { conf } from "@/setup/config";
|
||||||
|
|
||||||
export interface TurnstileStore {
|
export interface TurnstileStore {
|
||||||
@ -52,11 +53,18 @@ export function isTurnstileInitialized() {
|
|||||||
return !!getTurnstile();
|
return !!getTurnstile();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getTurnstileToken() {
|
export async function getTurnstileToken() {
|
||||||
const turnstile = getTurnstile();
|
const turnstile = getTurnstile();
|
||||||
turnstile?.reset();
|
turnstile?.reset();
|
||||||
turnstile?.execute();
|
turnstile?.execute();
|
||||||
return useTurnstileStore.getState().getToken();
|
try {
|
||||||
|
const token = await useTurnstileStore.getState().getToken();
|
||||||
|
reportCaptchaSolve(true);
|
||||||
|
return token;
|
||||||
|
} catch (err) {
|
||||||
|
reportCaptchaSolve(false);
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function TurnstileProvider() {
|
export function TurnstileProvider() {
|
||||||
|
Loading…
Reference in New Issue
Block a user