one
Version:
One is a React framework for web, iOS, and Android apps.
243 lines (240 loc) • 7.55 kB
JavaScript
import { Fragment, jsx } from "react/jsx-runtime";
import { useIsFocused } from "@react-navigation/core";
import React from "react";
import { useParams, usePathname, useSegments, useUnstableGlobalHref } from "../hooks.native.js";
import { HeadModule } from "./HeadModule.native.js";
import { getStaticUrlFromOneRouter } from "./url.native.js";
function urlToId(url) {
return url.replace(/[^a-zA-Z0-9]/g, "-");
}
function getLastSegment(path) {
var _path_split_pop;
var lastSegment = (_path_split_pop = path.split("/").pop()) !== null && _path_split_pop !== void 0 ? _path_split_pop : "";
return lastSegment.replace(/\.[^/.]+$/, "").split("?")[0];
}
function useAddressableLink() {
var pathname = useUnstableGlobalHref();
var params = useParams();
var url = getStaticUrlFromOneRouter(pathname);
return {
url,
pathname,
params
};
}
function useMetaChildren(children) {
return React.useMemo(function() {
var renderableChildren = [];
var metaChildren = [];
React.Children.forEach(children, function(child) {
if (!/* @__PURE__ */ React.isValidElement(child)) {
return;
}
if (typeof child.type === "string") {
metaChildren.push(child);
} else {
renderableChildren.push(child);
}
});
return {
children: renderableChildren,
metaChildren
};
}, [children]);
}
function serializedMetaChildren(meta) {
var validMeta = meta.filter(function(child) {
return child.type === "meta" || child.type === "title";
});
return validMeta.map(function(child) {
if (child.type === "title") {
return {
type: "title",
props: { children: child.props && typeof child.props === "object" && "children" in child.props && typeof child.props.children === "string" ? child.props.children : void 0 }
};
}
return {
type: "meta",
props: {
property: child.props && typeof child.props === "object" && "property" in child.props && typeof child.props.property === "string" ? child.props.property : void 0,
content: child.props && typeof child.props === "object" && "content" in child.props && typeof child.props.content === "string" ? child.props.content : void 0
}
};
});
}
function useActivityFromMetaChildren(meta) {
var { url: href, pathname } = useAddressableLink();
var previousMeta = React.useRef([]);
var cachedActivity = React.useRef({});
var sortedMeta = React.useMemo(function() {
return serializedMetaChildren(meta);
}, [meta]);
var url = React.useMemo(function() {
var urlMeta = sortedMeta.find(function(child) {
return child.type === "meta" && child.props.property === "og:url";
});
if (urlMeta) {
var _urlMeta_props_content;
if ((_urlMeta_props_content = urlMeta.props.content) === null || _urlMeta_props_content === void 0 ? void 0 : _urlMeta_props_content.startsWith("/")) {
return getStaticUrlFromOneRouter(urlMeta.props.content);
}
return urlMeta.props.content;
}
return href;
}, [sortedMeta, href]);
var title = React.useMemo(function() {
var titleTag = sortedMeta.find(function(child) {
return child.type === "title";
});
if (titleTag) {
var _titleTag_props_children;
return (_titleTag_props_children = titleTag.props.children) !== null && _titleTag_props_children !== void 0 ? _titleTag_props_children : "";
}
var titleMeta = sortedMeta.find(function(child) {
return child.type === "meta" && child.props.property === "og:title";
});
if (titleMeta) {
var _titleMeta_props_content;
return (_titleMeta_props_content = titleMeta.props.content) !== null && _titleMeta_props_content !== void 0 ? _titleMeta_props_content : "";
}
return getLastSegment(pathname);
}, [sortedMeta, pathname]);
var activity = React.useMemo(function() {
if (!!previousMeta.current && !!cachedActivity.current && deepObjectCompare(previousMeta.current, sortedMeta)) {
return cachedActivity.current;
}
previousMeta.current = sortedMeta;
var userActivity = {};
sortedMeta.forEach(function(child) {
if (child.type === "meta") {
var { property, content } = child.props;
switch (property) {
case "og:description":
userActivity.description = content;
break;
case "expo:handoff":
userActivity.isEligibleForHandoff = isTruthy(content);
break;
case "expo:spotlight":
userActivity.isEligibleForSearch = isTruthy(content);
break;
}
}
});
cachedActivity.current = userActivity;
return userActivity;
}, [sortedMeta]);
var parsedActivity = {
keywords: [title],
...activity,
title,
webpageURL: url,
activityType: Head.activities.INDEXED_ROUTE,
userInfo: { href }
};
return parsedActivity;
}
function isTruthy(value) {
return [true, "true"].includes(value);
}
function HeadNative(props) {
var isFocused = useIsFocused();
if (!isFocused) {
return /* @__PURE__ */ jsx(UnfocusedHead, {});
}
return /* @__PURE__ */ jsx(FocusedHead, { ...props });
}
function UnfocusedHead(props) {
var { children } = useMetaChildren(props.children);
return /* @__PURE__ */ jsx(Fragment, { children });
}
function FocusedHead(props) {
var { metaChildren, children } = useMetaChildren(props.children);
var activity = useActivityFromMetaChildren(metaChildren);
useRegisterCurrentActivity(activity);
return /* @__PURE__ */ jsx(Fragment, { children });
}
var activities = /* @__PURE__ */ new Map();
function useRegisterCurrentActivity(activity) {
var activityId = urlToId(usePathname() || "/");
var cascadingId = urlToId(useSegments().join("-") || "-");
var cascadingActivity = React.useMemo(function() {
var cascadingActivity2 = activities.has(cascadingId) ? {
...activities.get(cascadingId),
...activity,
id: activityId
} : {
...activity,
id: activityId
};
activities.set(cascadingId, cascadingActivity2);
return cascadingActivity2;
}, [
cascadingId,
activityId,
activity
]);
var previousActivity = React.useRef(null);
React.useEffect(function() {
if (!cascadingActivity) {
return function() {};
}
if (!!previousActivity.current && deepObjectCompare(previousActivity.current, cascadingActivity)) {
return function() {};
}
previousActivity.current = cascadingActivity;
if (!cascadingActivity.id) {
throw new Error("Activity must have an ID");
}
if (cascadingActivity.isEligibleForHandoff || cascadingActivity.isEligibleForSearch) {
Head === null || Head === void 0 ? void 0 : Head.createActivity(cascadingActivity);
}
return function() {};
}, [cascadingActivity]);
React.useEffect(function() {
return function() {
if (activityId) {
HeadModule === null || HeadModule === void 0 ? void 0 : HeadModule.suspendActivity(activityId);
}
};
}, [activityId]);
}
function deepObjectCompare(a, b) {
if (typeof a !== typeof b) {
return false;
}
if (typeof a === "object") {
if (Array.isArray(a) !== Array.isArray(b)) {
return false;
}
if (Array.isArray(a)) {
if (a.length !== b.length) {
return false;
}
return a.every(function(item, index) {
return deepObjectCompare(item, b[index]);
});
}
if (a === null || b === null) {
return a === b;
}
var aKeys = Object.keys(a);
var bKeys = Object.keys(b);
if (aKeys.length !== bKeys.length) {
return false;
}
return aKeys.every(function(key) {
return deepObjectCompare(a[key], b[key]);
});
}
return a === b;
}
HeadNative.Provider = React.Fragment;
function HeadShim(props) {
return null;
}
HeadShim.Provider = React.Fragment;
var Head = HeadModule ? HeadNative : HeadShim;
Object.assign(Head, HeadModule);
export { Head };
//# sourceMappingURL=Head.ios.js.map