diff --git a/netlify.toml b/netlify.toml index f52e1186..3876b472 100644 --- a/netlify.toml +++ b/netlify.toml @@ -13,7 +13,12 @@ ID = "be420a16-4ef3-43b1-ac62-35869bdf8679" # Default build command. command = "npm run build" +[[redirects]] + from = "/sitemap.xml*" + to = "https://api.webamp.org/sitemap.xml" + status = 200 + [[redirects]] from = "/*" to = "/index.html" - status = 200 \ No newline at end of file + status = 200 diff --git a/src/FocusedSkin.js b/src/FocusedSkin.js index 8562e605..fdc76885 100644 --- a/src/FocusedSkin.js +++ b/src/FocusedSkin.js @@ -52,7 +52,7 @@ function FocusedSkin() { const [previewLoaded, setPreviewLoaded] = useState(initialPosition != null); const centeredState = useCenteredState(); const closeModal = useActionCreator(Actions.closeModal); - const skinData = useSelector((state) => state.skins[hash] || null); + const skinData = useSelector(Selectors.getSelectedSkinData); const pos = initialPosition == null || centered ? centeredState : initialPosition; diff --git a/src/Head.js b/src/Head.js index 754be31d..56072ae9 100644 --- a/src/Head.js +++ b/src/Head.js @@ -4,56 +4,51 @@ import { Helmet } from "react-helmet"; import * as Selectors from "./redux/selectors"; import { SCREENSHOT_WIDTH, SCREENSHOT_HEIGHT } from "./constants"; -class Head extends React.Component { - render() { - return ( - - - {this.props.pageTitle} - - +function Head(props) { + return ( + + + {props.pageTitle} + + + + + + {props.previewImageUrl && [ + property="og:image" + key="og:image" + content={props.previewImageUrl} + />, - - {this.props.previewImageUrl && [ - , - , - , - , - , - ]} - - ); - } + property="og:image:type" + key="og:image:type" + content="image/png" + />, + , + , + , + ]} + + ); } const mapStateToProps = (state) => ({ diff --git a/src/redux/selectors.js b/src/redux/selectors.js index 1cb50716..338115a2 100644 --- a/src/redux/selectors.js +++ b/src/redux/selectors.js @@ -10,6 +10,15 @@ export function getSelectedSkinPosition(state) { return state.selectedSkinPosition; } +export function getSelectedSkinData(state) { + const hash = getSelectedSkinHash(state); + if (hash == null) { + return null; + } + + return state.skins[hash] || null; +} + export function overlayShouldAnimate(state) { return getSelectedSkinPosition(state) != null; } @@ -136,44 +145,57 @@ export const getAbsolutePermalinkUrlFromHashGetter = createSelector( } ); -export const getUrl = createSelector( +export const getRouteData = createSelector( getActiveContentPage, getSelectedSkinHash, getSearchQuery, getFileExplorerOpen, getFocusedSkinFile, getPermalinkUrlFromHashGetter, + getSelectedSkinData, ( activeContentPage, hash, query, fileExplorerOpen, focusedSkinFile, - getPermalinkUrlFromHash + getPermalinkUrlFromHash, + skinData ) => { if (activeContentPage === ABOUT_PAGE) { - return "/about/"; + return { url: "/about/", title: "About" }; } if (activeContentPage === UPLOAD_PAGE) { - return "/upload/"; + return { url: "/upload/", title: "Upload Skins" }; } if (hash) { const skinUrl = getPermalinkUrlFromHash(hash); if (fileExplorerOpen && focusedSkinFile) { - return `${skinUrl}files/${encodeURIComponent( + const url = `${skinUrl}files/${encodeURIComponent( focusedSkinFile.fileName )}`; + return { url, title: skinData?.fileName }; } - return skinUrl; + return { url: skinUrl, title: skinData?.fileName }; } else if (query) { - return `/?query=${encodeURIComponent(query)}`; + return { + url: `/?query=${encodeURIComponent(query)}`, + title: `Search: ${query}`, + }; } - return "/"; + return { url: "/", title: null }; } ); +export const getUrl = createSelector(getRouteData, (routeData) => { + return routeData.url; +}); + export function getPageTitle(state) { - return "Winamp Skin Museum"; + const routeData = getRouteData(state); + const pageTitle = routeData.title; + const siteTitle = "Winamp Skin Museum"; + return [pageTitle, siteTitle].filter(Boolean).join(" - "); } export const getPreviewImageUrl = createSelector(