mirror of
https://github.com/movie-web/movie-web.git
synced 2025-09-13 18:13:24 +00:00
finalized domain redirect modal
Co-authored-by: Jip Frijlink <JipFr@users.noreply.github.com> Co-authored-by: James Hawkins <jhawki2005@gmail.com>
This commit is contained in:
@@ -7,17 +7,15 @@ interface Props {
|
|||||||
children?: ReactNode;
|
children?: ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO style button
|
|
||||||
// TODO transition modal
|
|
||||||
export function Button(props: Props) {
|
export function Button(props: Props) {
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={props.onClick}
|
onClick={props.onClick}
|
||||||
className="inline-flex items-center justify-center"
|
className="inline-flex items-center justify-center rounded-lg bg-white px-8 py-3 font-bold text-black transition-[transform,background-color] duration-100 hover:bg-gray-200 active:scale-105 md:px-16"
|
||||||
>
|
>
|
||||||
{props.icon ? (
|
{props.icon ? (
|
||||||
<span className="mr-3">
|
<span className="mr-3 hidden md:inline-block">
|
||||||
<Icon icon={props.icon} />
|
<Icon icon={props.icon} />
|
||||||
</span>
|
</span>
|
||||||
) : null}
|
) : null}
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
import { Transition } from "@/components/Transition";
|
||||||
import { Helmet } from "react-helmet";
|
import { Helmet } from "react-helmet";
|
||||||
|
|
||||||
export function Overlay(props: { children: React.ReactNode }) {
|
export function Overlay(props: { children: React.ReactNode }) {
|
||||||
@@ -6,7 +7,12 @@ export function Overlay(props: { children: React.ReactNode }) {
|
|||||||
<Helmet>
|
<Helmet>
|
||||||
<body data-no-scroll />
|
<body data-no-scroll />
|
||||||
</Helmet>
|
</Helmet>
|
||||||
<div className="fixed inset-0 z-[99999] flex h-full w-full items-center justify-center bg-[rgba(8,6,18,0.85)]">
|
<div className="fixed inset-0 z-[99999]">
|
||||||
|
<Transition
|
||||||
|
animation="fade"
|
||||||
|
className="absolute inset-0 bg-[rgba(8,6,18,0.85)]"
|
||||||
|
isChild
|
||||||
|
/>
|
||||||
{props.children}
|
{props.children}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
@@ -4,14 +4,16 @@ import {
|
|||||||
TransitionClasses,
|
TransitionClasses,
|
||||||
} from "@headlessui/react";
|
} from "@headlessui/react";
|
||||||
|
|
||||||
type TransitionAnimations = "slide-down" | "slide-up" | "fade";
|
type TransitionAnimations = "slide-down" | "slide-up" | "fade" | "none";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
show: boolean;
|
show?: boolean;
|
||||||
durationClass?: string;
|
durationClass?: string;
|
||||||
animation: TransitionAnimations;
|
animation: TransitionAnimations;
|
||||||
className?: string;
|
className?: string;
|
||||||
children?: ReactNode;
|
children?: ReactNode;
|
||||||
|
appearOnMount?: boolean;
|
||||||
|
isChild?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getClasses(
|
function getClasses(
|
||||||
@@ -58,8 +60,25 @@ export function Transition(props: Props) {
|
|||||||
const duration = props.durationClass ?? "duration-200";
|
const duration = props.durationClass ?? "duration-200";
|
||||||
const classes = getClasses(props.animation, duration);
|
const classes = getClasses(props.animation, duration);
|
||||||
|
|
||||||
|
if (props.isChild) {
|
||||||
return (
|
return (
|
||||||
<HeadlessTransition show={props.show} as={Fragment} {...classes}>
|
<HeadlessTransition.Child
|
||||||
|
as={Fragment}
|
||||||
|
appear={props.appearOnMount}
|
||||||
|
{...classes}
|
||||||
|
>
|
||||||
|
<div className={props.className}>{props.children}</div>
|
||||||
|
</HeadlessTransition.Child>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<HeadlessTransition
|
||||||
|
show={props.show}
|
||||||
|
as={Fragment}
|
||||||
|
appear={props.appearOnMount}
|
||||||
|
{...classes}
|
||||||
|
>
|
||||||
<div className={props.className}>{props.children}</div>
|
<div className={props.className}>{props.children}</div>
|
||||||
</HeadlessTransition>
|
</HeadlessTransition>
|
||||||
);
|
);
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
import { Overlay } from "@/components/Overlay";
|
import { Overlay } from "@/components/Overlay";
|
||||||
|
import { Transition } from "@/components/Transition";
|
||||||
import { ReactNode } from "react";
|
import { ReactNode } from "react";
|
||||||
import { createPortal } from "react-dom";
|
import { createPortal } from "react-dom";
|
||||||
|
|
||||||
@@ -7,18 +8,38 @@ interface Props {
|
|||||||
children?: ReactNode;
|
children?: ReactNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ModalFrame(props: { children?: ReactNode }) {
|
export function ModalFrame(props: Props) {
|
||||||
return <Overlay>{props.children}</Overlay>;
|
return (
|
||||||
|
<Transition
|
||||||
|
className="fixed inset-0 z-[9999]"
|
||||||
|
animation="none"
|
||||||
|
appearOnMount
|
||||||
|
show={props.show}
|
||||||
|
>
|
||||||
|
<Overlay>
|
||||||
|
<Transition
|
||||||
|
isChild
|
||||||
|
appearOnMount
|
||||||
|
className="flex h-full w-full items-center justify-center"
|
||||||
|
animation="slide-up"
|
||||||
|
>
|
||||||
|
{props.children}
|
||||||
|
</Transition>
|
||||||
|
</Overlay>
|
||||||
|
</Transition>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Modal(props: Props) {
|
export function Modal(props: Props) {
|
||||||
if (!props.show) return null;
|
return createPortal(
|
||||||
return createPortal(<ModalFrame>{props.children}</ModalFrame>, document.body);
|
<ModalFrame show={props.show}>{props.children}</ModalFrame>,
|
||||||
|
document.body
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ModalCard(props: { children?: ReactNode }) {
|
export function ModalCard(props: { children?: ReactNode }) {
|
||||||
return (
|
return (
|
||||||
<div className="relative w-4/5 max-w-[600px] overflow-hidden rounded-lg bg-denim-200 px-10 py-10">
|
<div className="relative mx-2 max-w-[600px] overflow-hidden rounded-lg bg-denim-200 px-10 py-10">
|
||||||
{props.children}
|
{props.children}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@@ -79,9 +79,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"v3": {
|
"v3": {
|
||||||
"newSiteTitle": "We have a new site!",
|
"newSiteTitle": "Version 3 has released!",
|
||||||
"newDomain": "https://movie-web.app",
|
"newDomain": "https://movie-web.app",
|
||||||
"newDomainText": "We've moved from domain, you can now access our website on <0>https://movie-web.app</0>. Make sure to change all your bookmarks as <1>the old link will stop working on 25 Febuary 2023.</1>",
|
"newDomainText": "We have a new domain. You can now access our website on <0>https://movie-web.app</0>. Make sure to update all your bookmarks as <1>the old link will stop working on {{date}}.</1>",
|
||||||
"tireless": "We've worked tirelessly on this new update, we hope you will enjoy what we've been cooking up for the past months."
|
"tireless": "We've worked tirelessly on this new update, we hope you will enjoy what we've been cooking up for the past months."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import pako from "pako";
|
import pako from "pako";
|
||||||
|
import { MWMediaType } from "@/backend/metadata/types";
|
||||||
|
import { conf } from "@/setup/config";
|
||||||
|
|
||||||
function fromBinary(str: string): Uint8Array {
|
function fromBinary(str: string): Uint8Array {
|
||||||
const result = new Uint8Array(str.length);
|
const result = new Uint8Array(str.length);
|
||||||
@@ -57,8 +59,13 @@ export function V2MigrationView() {
|
|||||||
const newParams = [] as string[];
|
const newParams = [] as string[];
|
||||||
newUrl.searchParams.forEach((_, key) => newParams.push(key));
|
newUrl.searchParams.forEach((_, key) => newParams.push(key));
|
||||||
newParams.forEach((v) => newUrl.searchParams.delete(v));
|
newParams.forEach((v) => newUrl.searchParams.delete(v));
|
||||||
|
newUrl.searchParams.append("migrated", "1");
|
||||||
|
|
||||||
newUrl.hash = "";
|
// hash router compatibility
|
||||||
|
newUrl.hash = conf().NORMAL_ROUTER ? "" : `/search/${MWMediaType.MOVIE}`;
|
||||||
|
newUrl.pathname = conf().NORMAL_ROUTER
|
||||||
|
? `/search/${MWMediaType.MOVIE}`
|
||||||
|
: "";
|
||||||
|
|
||||||
window.location.href = newUrl.toString();
|
window.location.href = newUrl.toString();
|
||||||
}, [done]);
|
}, [done]);
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import { Trans, useTranslation } from "react-i18next";
|
import { Trans, useTranslation } from "react-i18next";
|
||||||
import { Icon, Icons } from "@/components/Icon";
|
import { Icons } from "@/components/Icon";
|
||||||
import { SectionHeading } from "@/components/layout/SectionHeading";
|
import { SectionHeading } from "@/components/layout/SectionHeading";
|
||||||
import { MediaGrid } from "@/components/media/MediaGrid";
|
import { MediaGrid } from "@/components/media/MediaGrid";
|
||||||
import {
|
import {
|
||||||
@@ -86,6 +86,7 @@ function NewDomainModal() {
|
|||||||
const [show, setShow] = useState(
|
const [show, setShow] = useState(
|
||||||
new URLSearchParams(window.location.search).get("migrated") === "1"
|
new URLSearchParams(window.location.search).get("migrated") === "1"
|
||||||
);
|
);
|
||||||
|
const [loaded, setLoaded] = useState(false);
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
@@ -97,9 +98,41 @@ function NewDomainModal() {
|
|||||||
});
|
});
|
||||||
}, [history]);
|
}, [history]);
|
||||||
|
|
||||||
// Hi Isra! (TODO remove this in the future lol)
|
useEffect(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
setLoaded(true);
|
||||||
|
}, 500);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// If you see this bit of code, don't snitch!
|
||||||
|
// We need to urge users to update their bookmarks and usage,
|
||||||
|
// so we're putting a fake deadline that's only 2 weeks away.
|
||||||
|
const day = 1e3 * 60 * 60 * 24;
|
||||||
|
const months = [
|
||||||
|
"January",
|
||||||
|
"February",
|
||||||
|
"March",
|
||||||
|
"April",
|
||||||
|
"May",
|
||||||
|
"June",
|
||||||
|
"July",
|
||||||
|
"August",
|
||||||
|
"September",
|
||||||
|
"October",
|
||||||
|
"November",
|
||||||
|
"December",
|
||||||
|
];
|
||||||
|
const firstVisitToSite = new Date(
|
||||||
|
localStorage.getItem("firstVisitToSite") || Date.now()
|
||||||
|
);
|
||||||
|
localStorage.setItem("firstVisitToSite", firstVisitToSite.toISOString());
|
||||||
|
const fakeEndResult = new Date(firstVisitToSite.getTime() + 14 * day);
|
||||||
|
const endDateString = `${fakeEndResult.getDate()} ${
|
||||||
|
months[fakeEndResult.getMonth()]
|
||||||
|
} ${fakeEndResult.getFullYear()}`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal show={show}>
|
<Modal show={show && loaded}>
|
||||||
<ModalCard>
|
<ModalCard>
|
||||||
<div className="mb-12">
|
<div className="mb-12">
|
||||||
<div
|
<div
|
||||||
@@ -109,7 +142,7 @@ function NewDomainModal() {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<div className="relative flex items-center justify-center">
|
<div className="relative flex items-center justify-center">
|
||||||
<div className="rounded-full bg-bink-200 py-4 px-12 text-xl font-bold text-white">
|
<div className="rounded-full bg-bink-200 py-4 px-12 text-center text-sm font-bold text-white md:text-xl">
|
||||||
{t("v3.newDomain")}
|
{t("v3.newDomain")}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -119,8 +152,8 @@ function NewDomainModal() {
|
|||||||
{t("v3.newSiteTitle")}
|
{t("v3.newSiteTitle")}
|
||||||
</h2>
|
</h2>
|
||||||
<p className="leading-7">
|
<p className="leading-7">
|
||||||
<Trans i18nKey="v3.newDomainText">
|
<Trans i18nKey="v3.newDomainText" values={{ date: endDateString }}>
|
||||||
<span className="font-bold text-white" />
|
<span className="text-slate-300" />
|
||||||
<span className="font-bold text-white" />
|
<span className="font-bold text-white" />
|
||||||
</Trans>
|
</Trans>
|
||||||
</p>
|
</p>
|
||||||
|
Reference in New Issue
Block a user