mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-17 13:05:32 +09:00
fix(app): make the invite splash cover the whole page (#3427)
This commit is contained in:
1 parent
d2173fe879
commit
64cb159d65
4 files changed
+21
-87
No files matched your search
@@ -54,17 +54,6 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.rightSplit {
|
|
||||||
bottom: 0;
|
|
||||||
inset-inline-end: 0;
|
|
||||||
opacity: 1;
|
|
||||||
pointer-events: none;
|
|
||||||
position: fixed;
|
|
||||||
transition: opacity 0.4s ease;
|
|
||||||
width: auto;
|
|
||||||
z-index: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.leftSplit {
|
.leftSplit {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -126,10 +115,9 @@
|
|||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.splashImage {
|
.splashBackdrop {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
right: 0;
|
inset: 0;
|
||||||
bottom: 0;
|
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ import {Scroller, type ScrollerHandle} from '@app/features/ui/components/Scrolle
|
|||||||
import {isMobileExperienceEnabled} from '@app/features/ui/utils/MobileExperience';
|
import {isMobileExperienceEnabled} from '@app/features/ui/utils/MobileExperience';
|
||||||
import {hasUnavailableElectronNativeContext} from '@app/features/ui/utils/NativeUtils';
|
import {hasUnavailableElectronNativeContext} from '@app/features/ui/utils/NativeUtils';
|
||||||
import {useNativeTitleBar} from '@app/features/window/hooks/useNativeTitleBar';
|
import {useNativeTitleBar} from '@app/features/window/hooks/useNativeTitleBar';
|
||||||
import Window from '@app/features/window/state/Window';
|
|
||||||
import {flxElementClassName} from '@app/lib/react';
|
import {flxElementClassName} from '@app/lib/react';
|
||||||
import type {GuildSplashCardAlignmentValue} from '@fluxer/constants/src/GuildConstants';
|
import type {GuildSplashCardAlignmentValue} from '@fluxer/constants/src/GuildConstants';
|
||||||
import {GuildSplashCardAlignment} from '@fluxer/constants/src/GuildConstants';
|
import {GuildSplashCardAlignment} from '@fluxer/constants/src/GuildConstants';
|
||||||
@@ -65,7 +64,6 @@ function resolveAuthLayoutContentMode({current, value}: ResolveAuthLayoutContent
|
|||||||
}
|
}
|
||||||
|
|
||||||
const AuthLayoutContent = observer(function AuthLayoutContent({children}: {children?: ReactNode}) {
|
const AuthLayoutContent = observer(function AuthLayoutContent({children}: {children?: ReactNode}) {
|
||||||
const {width: viewportWidth, height: viewportHeight} = Window.windowSize;
|
|
||||||
const [splashUrl, setSplashUrl] = useState<string | null>(null);
|
const [splashUrl, setSplashUrl] = useState<string | null>(null);
|
||||||
const [cardVariant, setCardVariant] = useState<AuthCardVariant>('default');
|
const [cardVariant, setCardVariant] = useState<AuthCardVariant>('default');
|
||||||
const [contentMode, setContentMode] = useState<AuthLayoutContentMode | null>(null);
|
const [contentMode, setContentMode] = useState<AuthLayoutContentMode | null>(null);
|
||||||
@@ -102,14 +100,6 @@ const AuthLayoutContent = observer(function AuthLayoutContent({children}: {child
|
|||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
setContentMode((current) => current ?? AuthLayoutContentMode.CARD);
|
setContentMode((current) => current ?? AuthLayoutContentMode.CARD);
|
||||||
}, []);
|
}, []);
|
||||||
const splashScale = useMemo(() => {
|
|
||||||
if (!splashDimensions) return null;
|
|
||||||
const {width, height} = splashDimensions;
|
|
||||||
if (width <= 0 || height <= 0) return null;
|
|
||||||
const heightScale = viewportHeight / height;
|
|
||||||
const widthScale = viewportWidth / width;
|
|
||||||
return Math.max(heightScale, widthScale);
|
|
||||||
}, [splashDimensions, viewportHeight, viewportWidth]);
|
|
||||||
const handleSetContentMode = useCallback<Dispatch<SetStateAction<AuthLayoutContentMode>>>((value) => {
|
const handleSetContentMode = useCallback<Dispatch<SetStateAction<AuthLayoutContentMode>>>((value) => {
|
||||||
setContentMode((current) => resolveAuthLayoutContentMode({current, value}));
|
setContentMode((current) => resolveAuthLayoutContentMode({current, value}));
|
||||||
}, []);
|
}, []);
|
||||||
@@ -236,11 +226,10 @@ const AuthLayoutContent = observer(function AuthLayoutContent({children}: {child
|
|||||||
data-flx="app.auth-layout.auth-layout-content.character-background"
|
data-flx="app.auth-layout.auth-layout-content.character-background"
|
||||||
>
|
>
|
||||||
<AuthBackground
|
<AuthBackground
|
||||||
|
className={styles.splashBackdrop}
|
||||||
splashUrl={splashUrl}
|
splashUrl={splashUrl}
|
||||||
splashDimensions={splashDimensions}
|
splashDimensions={splashDimensions}
|
||||||
splashScale={splashScale}
|
|
||||||
splashAlignment={splashAlignment}
|
splashAlignment={splashAlignment}
|
||||||
useFullCover={false}
|
|
||||||
data-flx="app.auth-layout.auth-layout-content.auth-background"
|
data-flx="app.auth-layout.auth-layout-content.auth-background"
|
||||||
/>
|
/>
|
||||||
<flx-app-auth-layout-split
|
<flx-app-auth-layout-split
|
||||||
|
|||||||
@@ -5,91 +5,49 @@ import {GuildSplashCardAlignment} from '@fluxer/constants/src/GuildConstants';
|
|||||||
import type {ValueOf} from '@fluxer/constants/src/ValueOf';
|
import type {ValueOf} from '@fluxer/constants/src/ValueOf';
|
||||||
import type React from 'react';
|
import type React from 'react';
|
||||||
|
|
||||||
const getSplashAlignmentStyles = (alignment: ValueOf<typeof GuildSplashCardAlignment>) => {
|
const getSplashObjectPosition = (alignment: ValueOf<typeof GuildSplashCardAlignment>) => {
|
||||||
switch (alignment) {
|
switch (alignment) {
|
||||||
case GuildSplashCardAlignment.LEFT:
|
case GuildSplashCardAlignment.LEFT:
|
||||||
return {transformOrigin: 'bottom left', objectPosition: 'left bottom'};
|
return 'left bottom';
|
||||||
case GuildSplashCardAlignment.RIGHT:
|
case GuildSplashCardAlignment.RIGHT:
|
||||||
return {transformOrigin: 'bottom right', objectPosition: 'right bottom'};
|
return 'right bottom';
|
||||||
default:
|
default:
|
||||||
return {transformOrigin: 'bottom center', objectPosition: 'center bottom'};
|
return 'center bottom';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface AuthBackgroundProps {
|
export interface AuthBackgroundProps {
|
||||||
splashUrl: string | null;
|
splashUrl: string | null;
|
||||||
splashDimensions?: {width: number; height: number} | null;
|
splashDimensions?: {width: number; height: number} | null;
|
||||||
splashScale?: number | null;
|
|
||||||
patternImageUrl?: string | null;
|
patternImageUrl?: string | null;
|
||||||
className?: string;
|
className?: string;
|
||||||
useFullCover?: boolean;
|
|
||||||
splashAlignment?: ValueOf<typeof GuildSplashCardAlignment>;
|
splashAlignment?: ValueOf<typeof GuildSplashCardAlignment>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AuthBackground: React.FC<AuthBackgroundProps> = ({
|
export const AuthBackground: React.FC<AuthBackgroundProps> = ({
|
||||||
splashUrl,
|
splashUrl,
|
||||||
splashDimensions,
|
splashDimensions,
|
||||||
splashScale,
|
|
||||||
patternImageUrl,
|
patternImageUrl,
|
||||||
className,
|
className,
|
||||||
useFullCover = false,
|
|
||||||
splashAlignment = GuildSplashCardAlignment.CENTER,
|
splashAlignment = GuildSplashCardAlignment.CENTER,
|
||||||
}) => {
|
}) => {
|
||||||
const shouldShowSplash = splashUrl && splashDimensions && (useFullCover || splashScale);
|
if (splashUrl && splashDimensions) {
|
||||||
const {transformOrigin, objectPosition} = getSplashAlignmentStyles(splashAlignment);
|
|
||||||
if (shouldShowSplash) {
|
|
||||||
if (useFullCover) {
|
|
||||||
return (
|
|
||||||
<div className={className} data-flx="auth.flow.auth-background.div">
|
|
||||||
<div style={{position: 'absolute', inset: 0}} data-flx="auth.flow.auth-background.div--2">
|
|
||||||
<img
|
|
||||||
src={splashUrl}
|
|
||||||
alt=""
|
|
||||||
style={{
|
|
||||||
position: 'absolute',
|
|
||||||
inset: 0,
|
|
||||||
width: '100%',
|
|
||||||
height: '100%',
|
|
||||||
objectFit: 'cover',
|
|
||||||
objectPosition,
|
|
||||||
}}
|
|
||||||
data-flx="auth.flow.auth-background.img"
|
|
||||||
/>
|
|
||||||
<div className={styles.splashOverlay} data-flx="auth.flow.auth-background.splash-overlay" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.rightSplit} data-flx="auth.flow.auth-background.right-split">
|
<div className={className} data-flx="auth.flow.auth-background.div">
|
||||||
<div
|
<img
|
||||||
className={styles.splashImage}
|
src={splashUrl}
|
||||||
|
alt=""
|
||||||
style={{
|
style={{
|
||||||
width: splashDimensions.width,
|
position: 'absolute',
|
||||||
height: splashDimensions.height,
|
inset: 0,
|
||||||
transform: `scale(${splashScale})`,
|
width: '100%',
|
||||||
transformOrigin,
|
height: '100%',
|
||||||
|
objectFit: 'cover',
|
||||||
|
objectPosition: getSplashObjectPosition(splashAlignment),
|
||||||
}}
|
}}
|
||||||
data-flx="auth.flow.auth-background.splash-image"
|
data-flx="auth.flow.auth-background.img"
|
||||||
>
|
/>
|
||||||
<img
|
<div className={styles.splashOverlay} data-flx="auth.flow.auth-background.splash-overlay" />
|
||||||
src={splashUrl}
|
|
||||||
alt=""
|
|
||||||
width={splashDimensions.width}
|
|
||||||
height={splashDimensions.height}
|
|
||||||
style={{
|
|
||||||
position: 'absolute',
|
|
||||||
left: 0,
|
|
||||||
top: 0,
|
|
||||||
width: '100%',
|
|
||||||
height: '100%',
|
|
||||||
objectFit: 'cover',
|
|
||||||
objectPosition,
|
|
||||||
}}
|
|
||||||
data-flx="auth.flow.auth-background.img--2"
|
|
||||||
/>
|
|
||||||
<div className={styles.splashOverlay} data-flx="auth.flow.auth-background.splash-overlay--2" />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -125,7 +125,6 @@ export const InvitePagePreviewModal: React.FC<InvitePagePreviewModalProps> = obs
|
|||||||
splashDimensions={splashDimensions}
|
splashDimensions={splashDimensions}
|
||||||
patternImageUrl={patternReady ? foodPatternUrl : null}
|
patternImageUrl={patternReady ? foodPatternUrl : null}
|
||||||
splashAlignment={splashAlignment}
|
splashAlignment={splashAlignment}
|
||||||
useFullCover={true}
|
|
||||||
data-flx="invite.invite-page-preview-modal.background"
|
data-flx="invite.invite-page-preview-modal.background"
|
||||||
/>
|
/>
|
||||||
<div className={styles.foreground} data-flx="invite.invite-page-preview-modal.foreground">
|
<div className={styles.foreground} data-flx="invite.invite-page-preview-modal.foreground">
|
||||||
|
|||||||
Reference in new issue
Block a user