Merge branch 'site-logo' into 'develop'
Replace logos with SiteLogo component, fixes #937 Closes #937 See merge request soapbox-pub/soapbox-fe!1356
This commit is contained in:
commit
80f5c75a1a
14 changed files with 86 additions and 124 deletions
1
app/images/soapbox-logo-white.svg
Normal file
1
app/images/soapbox-logo-white.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 95 95" width="100" height="100"><path d="M94.909 19.374C94.909 8.674 86.235 0 75.534 0c-10.647 0-19.28 8.591-19.365 19.217l-15.631 2.09c-1.961-6.007-7.598-10.35-14.258-10.35-8.284 0-15.002 6.716-15.002 15.002 0 6.642 4.321 12.267 10.303 14.24l-2.205 16.056c-10.66.049-19.285 8.7-19.285 19.37C.091 86.325 8.765 95 19.466 95c10.677 0 19.332-8.638 19.37-19.304l18.093-2.501c1.979 5.972 7.598 10.285 14.234 10.285 8.284 0 15.002-6.716 15.002-15.002 0-6.891-4.652-12.682-10.983-14.441l1.365-15.339c10.229-.53 18.363-8.966 18.363-19.324zM56.194 67.8l-18.116 2.505a19.39 19.39 0 0 0-13.312-13.3l2.205-16.077a14.98 14.98 0 0 0 14.27-14.222l15.655-2.094c1.894 6.757 7.351 12.009 14.225 13.612l-1.365 15.322c-7.4.688-13.224 6.753-13.562 14.254z" fill="#ffffff"/></svg>
|
After Width: | Height: | Size: 812 B |
|
@ -9,9 +9,10 @@ import { fetchOwnAccounts } from 'soapbox/actions/auth';
|
|||
import { getSettings } from 'soapbox/actions/settings';
|
||||
import { closeSidebar } from 'soapbox/actions/sidebar';
|
||||
import Account from 'soapbox/components/account';
|
||||
import SiteLogo from 'soapbox/components/site-logo';
|
||||
import { Stack } from 'soapbox/components/ui';
|
||||
import ProfileStats from 'soapbox/features/ui/components/profile_stats';
|
||||
import { useAppSelector, useSoapboxConfig, useFeatures } from 'soapbox/hooks';
|
||||
import { useAppSelector, useFeatures } from 'soapbox/hooks';
|
||||
import { makeGetAccount, makeGetOtherAccounts } from 'soapbox/selectors';
|
||||
import { getBaseURL } from 'soapbox/utils/accounts';
|
||||
|
||||
|
@ -66,7 +67,6 @@ const SidebarMenu: React.FC = (): JSX.Element | null => {
|
|||
const intl = useIntl();
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const { logo } = useSoapboxConfig();
|
||||
const features = useFeatures();
|
||||
const getAccount = makeGetAccount();
|
||||
const instance = useAppSelector((state) => state.instance);
|
||||
|
@ -141,15 +141,7 @@ const SidebarMenu: React.FC = (): JSX.Element | null => {
|
|||
<Stack space={4}>
|
||||
<HStack alignItems='center' justifyContent='between'>
|
||||
<Link to='/' onClick={onClose}>
|
||||
{logo ? (
|
||||
<img alt='Logo' src={logo} className='h-5 w-auto cursor-pointer' />
|
||||
) : (
|
||||
<Icon
|
||||
alt='Logo'
|
||||
src={require('@tabler/icons/icons/home.svg')}
|
||||
className='h-6 w-6 text-gray-400 hover:text-gray-600 dark:text-gray-200 cursor-pointer'
|
||||
/>
|
||||
)}
|
||||
<SiteLogo alt='Logo' className='h-5 w-auto cursor-pointer' />
|
||||
</Link>
|
||||
|
||||
<IconButton
|
||||
|
|
35
app/soapbox/components/site-logo.tsx
Normal file
35
app/soapbox/components/site-logo.tsx
Normal file
|
@ -0,0 +1,35 @@
|
|||
import React from 'react';
|
||||
|
||||
import { useSoapboxConfig, useSettings, useSystemTheme } from 'soapbox/hooks';
|
||||
|
||||
/** Display the most appropriate site logo based on the theme and configuration. */
|
||||
const SiteLogo: React.FC<React.ComponentProps<'img'>> = (props) => {
|
||||
const { logo, logoDarkMode } = useSoapboxConfig();
|
||||
const settings = useSettings();
|
||||
|
||||
const systemTheme = useSystemTheme();
|
||||
const userTheme = settings.get('themeMode');
|
||||
const darkMode = userTheme === 'dark' || (userTheme === 'system' && systemTheme === 'dark');
|
||||
|
||||
/** Soapbox logo. */
|
||||
const soapboxLogo = darkMode
|
||||
? require('images/soapbox-logo-white.svg')
|
||||
: require('images/soapbox-logo.svg');
|
||||
|
||||
// Use the right logo if provided, then use fallbacks.
|
||||
const getSrc = () => {
|
||||
// In demo mode, use the Soapbox logo.
|
||||
if (settings.get('demo')) return soapboxLogo;
|
||||
|
||||
return (darkMode && logoDarkMode)
|
||||
? logoDarkMode
|
||||
: logo || logoDarkMode || soapboxLogo;
|
||||
};
|
||||
|
||||
return (
|
||||
// eslint-disable-next-line jsx-a11y/alt-text
|
||||
<img src={getSrc()} {...props} />
|
||||
);
|
||||
};
|
||||
|
||||
export default SiteLogo;
|
|
@ -20,7 +20,7 @@ import PublicLayout from 'soapbox/features/public_layout';
|
|||
import NotificationsContainer from 'soapbox/features/ui/containers/notifications_container';
|
||||
import WaitlistPage from 'soapbox/features/verification/waitlist_page';
|
||||
import { createGlobals } from 'soapbox/globals';
|
||||
import { useAppSelector, useAppDispatch, useOwnAccount, useFeatures, useSoapboxConfig, useSettings } from 'soapbox/hooks';
|
||||
import { useAppSelector, useAppDispatch, useOwnAccount, useFeatures, useSoapboxConfig, useSettings, useSystemTheme } from 'soapbox/hooks';
|
||||
import MESSAGES from 'soapbox/locales/messages';
|
||||
import { generateThemeCss } from 'soapbox/utils/theme';
|
||||
|
||||
|
@ -82,17 +82,12 @@ const SoapboxMount = () => {
|
|||
const [localeLoading, setLocaleLoading] = useState(true);
|
||||
const [isLoaded, setIsLoaded] = useState(false);
|
||||
|
||||
const colorSchemeQueryList = window.matchMedia('(prefers-color-scheme: dark)');
|
||||
const [isSystemDarkMode, setSystemDarkMode] = useState(colorSchemeQueryList.matches);
|
||||
const systemTheme = useSystemTheme();
|
||||
const userTheme = settings.get('themeMode');
|
||||
const darkMode = userTheme === 'dark' || (userTheme === 'system' && isSystemDarkMode);
|
||||
const darkMode = userTheme === 'dark' || (userTheme === 'system' && systemTheme === 'dark');
|
||||
|
||||
const themeCss = generateThemeCss(soapboxConfig);
|
||||
|
||||
const handleSystemModeChange = (event: MediaQueryListEvent) => {
|
||||
setSystemDarkMode(event.matches);
|
||||
};
|
||||
|
||||
// Load the user's locale
|
||||
useEffect(() => {
|
||||
MESSAGES[locale]().then(messages => {
|
||||
|
@ -110,12 +105,6 @@ const SoapboxMount = () => {
|
|||
});
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
colorSchemeQueryList.addEventListener('change', handleSystemModeChange);
|
||||
|
||||
return () => colorSchemeQueryList.removeEventListener('change', handleSystemModeChange);
|
||||
}, []);
|
||||
|
||||
// @ts-ignore: I don't actually know what these should be, lol
|
||||
const shouldUpdateScroll = (prevRouterProps, { location }) => {
|
||||
return !(location.state?.soapboxModalKey && location.state?.soapboxModalKey !== prevRouterProps?.location?.state?.soapboxModalKey);
|
||||
|
|
|
@ -2,10 +2,10 @@ import React from 'react';
|
|||
import { Link, Redirect, Route, Switch } from 'react-router-dom';
|
||||
|
||||
import LandingGradient from 'soapbox/components/landing-gradient';
|
||||
import SvgIcon from 'soapbox/components/ui/icon/svg-icon';
|
||||
import SiteLogo from 'soapbox/components/site-logo';
|
||||
import BundleContainer from 'soapbox/features/ui/containers/bundle_container';
|
||||
import { NotificationsContainer } from 'soapbox/features/ui/util/async-components';
|
||||
import { useAppSelector, useSoapboxConfig } from 'soapbox/hooks';
|
||||
import { useAppSelector } from 'soapbox/hooks';
|
||||
|
||||
import { Card, CardBody } from '../../components/ui';
|
||||
import LoginPage from '../auth_login/components/login_page';
|
||||
|
@ -18,7 +18,6 @@ import Verification from '../verification';
|
|||
import EmailPassthru from '../verification/email_passthru';
|
||||
|
||||
const AuthLayout = () => {
|
||||
const { logo } = useSoapboxConfig();
|
||||
const siteTitle = useAppSelector(state => state.instance.title);
|
||||
|
||||
return (
|
||||
|
@ -29,15 +28,7 @@ const AuthLayout = () => {
|
|||
<div className='w-full sm:max-w-lg md:max-w-2xl space-y-8'>
|
||||
<header className='flex justify-center relative'>
|
||||
<Link to='/' className='cursor-pointer'>
|
||||
{logo ? (
|
||||
<img src={logo} alt={siteTitle} className='h-7' />
|
||||
) : (
|
||||
<SvgIcon
|
||||
className='w-7 h-7 dark:text-white'
|
||||
alt={siteTitle}
|
||||
src={require('@tabler/icons/icons/home.svg')}
|
||||
/>
|
||||
)}
|
||||
<SiteLogo alt={siteTitle} className='h-7' />
|
||||
</Link>
|
||||
</header>
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import classNames from 'classnames';
|
||||
import React from 'react';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import { useDispatch } from 'react-redux';
|
||||
|
@ -6,6 +5,7 @@ import { Link, Redirect } from 'react-router-dom';
|
|||
|
||||
import { logIn, verifyCredentials } from 'soapbox/actions/auth';
|
||||
import { fetchInstance } from 'soapbox/actions/instance';
|
||||
import SiteLogo from 'soapbox/components/site-logo';
|
||||
import { useAppSelector, useFeatures, useSoapboxConfig } from 'soapbox/hooks';
|
||||
|
||||
import { openModal } from '../../../actions/modals';
|
||||
|
@ -31,7 +31,6 @@ const Header = () => {
|
|||
const soapboxConfig = useSoapboxConfig();
|
||||
const pepeEnabled = soapboxConfig.getIn(['extensions', 'pepe', 'enabled']) === true;
|
||||
|
||||
const { logo, logoDarkMode } = soapboxConfig;
|
||||
const features = useFeatures();
|
||||
const instance = useAppSelector((state) => state.instance);
|
||||
const isOpen = features.accountCreation && instance.registrations;
|
||||
|
@ -80,11 +79,7 @@ const Header = () => {
|
|||
<Sonar />
|
||||
</div>
|
||||
<Link to='/' className='z-10'>
|
||||
<img alt='Logo' src={logo} className={classNames('h-6 w-auto cursor-pointer', { 'dark:hidden': logoDarkMode })} />
|
||||
{logoDarkMode && (
|
||||
<img alt='Logo' src={logoDarkMode} className='h-6 w-auto cursor-pointer hidden dark:block' />
|
||||
)}
|
||||
|
||||
<SiteLogo alt='Logo' className='h-6 w-auto cursor-pointer' />
|
||||
<span className='hidden'>{intl.formatMessage(messages.home)}</span>
|
||||
</Link>
|
||||
</div>
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
import React from 'react';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { getSoapboxConfig } from 'soapbox/actions/soapbox';
|
||||
|
||||
const mapStateToProps = (state, props) => ({
|
||||
instance: state.get('instance'),
|
||||
soapbox: getSoapboxConfig(state),
|
||||
});
|
||||
|
||||
class SiteBanner extends ImmutablePureComponent {
|
||||
|
||||
render() {
|
||||
const { instance, soapbox } = this.props;
|
||||
const logos = {
|
||||
imgLogo: (<img alt={instance.get('title')} src={soapbox.get('banner')} />),
|
||||
textLogo: (<h1>{instance.get('title')}</h1>),
|
||||
};
|
||||
return soapbox.getIn(['banner']) ? logos.imgLogo : logos.textLogo;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(SiteBanner);
|
|
@ -1,25 +0,0 @@
|
|||
import React from 'react';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { getSoapboxConfig } from 'soapbox/actions/soapbox';
|
||||
|
||||
const mapStateToProps = (state, props) => ({
|
||||
instance: state.get('instance'),
|
||||
soapbox: getSoapboxConfig(state),
|
||||
});
|
||||
|
||||
class SiteLogo extends ImmutablePureComponent {
|
||||
|
||||
render() {
|
||||
const { instance, soapbox } = this.props;
|
||||
const logos = {
|
||||
imgLogo: (<img alt={instance.get('title')} src={soapbox.get('logo')} />),
|
||||
textLogo: (<h1>{instance.get('title')}</h1>),
|
||||
};
|
||||
return soapbox.getIn(['logo']) ? logos.imgLogo : logos.textLogo;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(SiteLogo);
|
|
@ -4,6 +4,7 @@ import { FormattedMessage } from 'react-intl';
|
|||
|
||||
import { defaultSettings } from 'soapbox/actions/settings';
|
||||
import BackgroundShapes from 'soapbox/features/ui/components/background_shapes';
|
||||
import { useSystemTheme } from 'soapbox/hooks';
|
||||
import { normalizeSoapboxConfig } from 'soapbox/normalizers';
|
||||
import { generateThemeCss } from 'soapbox/utils/theme';
|
||||
|
||||
|
@ -17,7 +18,10 @@ const SitePreview: React.FC<ISitePreview> = ({ soapbox }) => {
|
|||
const soapboxConfig = useMemo(() => normalizeSoapboxConfig(soapbox), [soapbox]);
|
||||
const settings = defaultSettings.mergeDeep(soapboxConfig.defaultSettings);
|
||||
|
||||
const dark = settings.get('themeMode') === 'dark';
|
||||
const userTheme = settings.get('themeMode');
|
||||
const systemTheme = useSystemTheme();
|
||||
|
||||
const dark = userTheme === 'dark' || (userTheme === 'system' && systemTheme === 'dark');
|
||||
|
||||
const bodyClass = classNames(
|
||||
'site-preview',
|
||||
|
|
|
@ -2,6 +2,7 @@ import classNames from 'classnames';
|
|||
import React from 'react';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
|
||||
import SiteLogo from 'soapbox/components/site-logo';
|
||||
import { Button } from 'soapbox/components/ui';
|
||||
import { Modal } from 'soapbox/components/ui';
|
||||
import { useAppSelector, useFeatures, useSoapboxConfig } from 'soapbox/hooks';
|
||||
|
@ -23,7 +24,6 @@ const LandingPageModal: React.FC<ILandingPageModal> = ({ onClose }) => {
|
|||
const soapboxConfig = useSoapboxConfig();
|
||||
const pepeEnabled = soapboxConfig.getIn(['extensions', 'pepe', 'enabled']) === true;
|
||||
|
||||
const { logo } = soapboxConfig;
|
||||
const instance = useAppSelector((state) => state.instance);
|
||||
const features = useFeatures();
|
||||
|
||||
|
@ -32,7 +32,7 @@ const LandingPageModal: React.FC<ILandingPageModal> = ({ onClose }) => {
|
|||
|
||||
return (
|
||||
<Modal
|
||||
title={<img alt='Logo' src={logo} className='h-4 w-auto' />}
|
||||
title={<SiteLogo alt='Logo' className='h-4 w-auto' />}
|
||||
onClose={() => onClose('LANDING_PAGE')}
|
||||
>
|
||||
<div className='mt-4 divide-y divide-solid divide-gray-200 dark:divide-slate-700'>
|
||||
|
|
|
@ -4,9 +4,10 @@ import { FormattedMessage } from 'react-intl';
|
|||
import { useDispatch } from 'react-redux';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import { Avatar, Button, Icon } from 'soapbox/components/ui';
|
||||
import SiteLogo from 'soapbox/components/site-logo';
|
||||
import { Avatar, Button } from 'soapbox/components/ui';
|
||||
import Search from 'soapbox/features/compose/components/search';
|
||||
import { useOwnAccount, useSoapboxConfig, useSettings } from 'soapbox/hooks';
|
||||
import { useOwnAccount, useSoapboxConfig } from 'soapbox/hooks';
|
||||
|
||||
import { openSidebar } from '../../../actions/sidebar';
|
||||
|
||||
|
@ -17,14 +18,9 @@ const Navbar = () => {
|
|||
const node = React.useRef(null);
|
||||
|
||||
const account = useOwnAccount();
|
||||
const settings = useSettings();
|
||||
const soapboxConfig = useSoapboxConfig();
|
||||
const singleUserMode = soapboxConfig.get('singleUserMode');
|
||||
|
||||
// In demo mode, use the Soapbox logo
|
||||
const logo = settings.get('demo') ? require('images/soapbox-logo.svg') : soapboxConfig.logo;
|
||||
const logoDarkMode = soapboxConfig.logoDarkMode;
|
||||
|
||||
const onOpenSidebar = () => dispatch(openSidebar());
|
||||
|
||||
return (
|
||||
|
@ -46,21 +42,10 @@ const Navbar = () => {
|
|||
'justify-start': !account,
|
||||
})}
|
||||
>
|
||||
{logo ? (
|
||||
<Link key='logo' to='/' data-preview-title-id='column.home' className='flex-shrink-0 flex items-center'>
|
||||
<img alt='Logo' src={logo} className={classNames('h-5 lg:h-6 w-auto cursor-pointer', { 'dark:hidden': logoDarkMode })} />
|
||||
{logoDarkMode && (
|
||||
<img alt='Logo' src={logoDarkMode} className='h-5 lg:h-6 w-auto cursor-pointer hidden dark:block' />
|
||||
)}
|
||||
|
||||
<span className='hidden'><FormattedMessage id='tabs_bar.home' defaultMessage='Home' /></span>
|
||||
</Link>
|
||||
) : (
|
||||
<Link key='logo' to='/' data-preview-title-id='column.home' className='flex-shrink-0 flex items-center'>
|
||||
<Icon alt='Logo' src={require('@tabler/icons/icons/home.svg')} className='h-5 lg:h-6 w-auto text-primary-700' />
|
||||
<span className='hidden'><FormattedMessage id='tabs_bar.home' defaultMessage='Home' /></span>
|
||||
</Link>
|
||||
)}
|
||||
<Link key='logo' to='/' data-preview-title-id='column.home' className='flex-shrink-0 flex items-center'>
|
||||
<SiteLogo alt='Logo' className='h-5 lg:h-6 w-auto cursor-pointer' />
|
||||
<span className='hidden'><FormattedMessage id='tabs_bar.home' defaultMessage='Home' /></span>
|
||||
</Link>
|
||||
|
||||
{account && (
|
||||
<div className='flex-1 hidden lg:flex justify-center px-2 lg:ml-6 lg:justify-start items-center'>
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import { getSoapboxConfig } from 'soapbox/actions/soapbox';
|
||||
import LandingGradient from 'soapbox/components/landing-gradient';
|
||||
import SiteLogo from 'soapbox/components/site-logo';
|
||||
import BundleContainer from 'soapbox/features/ui/containers/bundle_container';
|
||||
import { NotificationsContainer } from 'soapbox/features/ui/util/async-components';
|
||||
|
||||
|
@ -16,8 +16,6 @@ const WaitlistPage = ({ account }) => {
|
|||
const dispatch = useDispatch();
|
||||
const intl = useIntl();
|
||||
|
||||
const logo = useSelector((state) => getSoapboxConfig(state).get('logo'));
|
||||
|
||||
const onClickLogOut = (event) => {
|
||||
event.preventDefault();
|
||||
dispatch(logOut(intl));
|
||||
|
@ -31,7 +29,7 @@ const WaitlistPage = ({ account }) => {
|
|||
<header className='relative flex justify-between h-16'>
|
||||
<div className='flex-1 flex items-stretch justify-center relative'>
|
||||
<Link to='/' className='cursor-pointer flex-shrink-0 flex items-center'>
|
||||
<img alt='Logo' src={logo} className='h-7' />
|
||||
<SiteLogo alt='Logo' className='h-7' />
|
||||
</Link>
|
||||
|
||||
<div className='absolute inset-y-0 right-0 flex items-center pr-2 space-x-3'>
|
||||
|
|
|
@ -6,3 +6,4 @@ export { useOnScreen } from './useOnScreen';
|
|||
export { useOwnAccount } from './useOwnAccount';
|
||||
export { useSettings } from './useSettings';
|
||||
export { useSoapboxConfig } from './useSoapboxConfig';
|
||||
export { useSystemTheme } from './useSystemTheme';
|
||||
|
|
21
app/soapbox/hooks/useSystemTheme.ts
Normal file
21
app/soapbox/hooks/useSystemTheme.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
import { useState, useEffect } from 'react';
|
||||
|
||||
type SystemTheme = 'light' | 'dark';
|
||||
|
||||
/** Get the system color scheme of the system. */
|
||||
export const useSystemTheme = (): SystemTheme => {
|
||||
const query = window.matchMedia('(prefers-color-scheme: dark)');
|
||||
const [dark, setDark] = useState(query.matches);
|
||||
|
||||
const handleChange = (event: MediaQueryListEvent) => {
|
||||
setDark(event.matches);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
query.addEventListener('change', handleChange);
|
||||
|
||||
return () => query.removeEventListener('change', handleChange);
|
||||
}, []);
|
||||
|
||||
return dark ? 'dark' : 'light';
|
||||
};
|
Loading…
Reference in a new issue