gatsby-theme-advanced
Version:
GatsbyJS theme equipped with advanced features.
76 lines (75 loc) • 3.79 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const react_1 = require("react");
const react_query_1 = require("react-query");
const useScrollBasedFetching_1 = __importDefault(require("./useScrollBasedFetching"));
const types_1 = require("../../types");
const config_1 = require("../../config");
// Calculate the base URL for the feed
const getBaseUrl = (pageContext, config) => `${config.pathPrefix}/${config_1.constants.feedMetaDirectory}${pageContext.feedType}${pageContext.feedId ? `-${pageContext.feedId}` : ""}`;
// Generate a fetch function for the feed
const getFetchFunc = (baseUrl) => ({ pageParam = 0 }) => __awaiter(void 0, void 0, void 0, function* () {
const response = yield fetch(`${baseUrl}-${pageParam}.json`);
if (!response.ok) {
throw new Error("Network response for fetching feed page was not ok.");
}
return response.json();
});
// Generate placeholders for currently loading posts
const createPostPlaceholders = (keyPrefix, count) => Array(count || config_1.constants.postsPerFeedPage)
.fill(0)
.map((_, idx) => ({
isPlaceholder: true,
key: `${keyPrefix}-${idx}`,
}));
const useInfiniteFeed = (pageContext) => {
const config = (0, config_1.useConfig)();
const baseUrl = getBaseUrl(pageContext, config);
// Setup an infinite feed query
const feedQuery = (0, react_query_1.useInfiniteQuery)([pageContext.feedType, pageContext.feedId], getFetchFunc(baseUrl), {
getNextPageParam: (lastPage) => lastPage.next,
// Set the initial page data supplied by the page context
initialData: {
pages: [pageContext.feedPageMeta],
pageParams: [pageContext.pageIndex],
},
});
const feedElementRef = (0, useScrollBasedFetching_1.default)(feedQuery);
// Memoize the postList
const feedListing = (0, react_1.useMemo)(() => {
var _a, _b, _c;
const jsonPostList = ((_a = feedQuery === null || feedQuery === void 0 ? void 0 : feedQuery.data) === null || _a === void 0 ? void 0 : _a.pages.map((page) => page.posts).flat()) ||
pageContext.feedPageMeta.posts;
const list = jsonPostList.map(types_1.jsonPostIntoPost);
// When loading the next page, show placeholder posts
if (feedQuery.isFetchingNextPage) {
const pageCount = (_b = feedQuery.data) === null || _b === void 0 ? void 0 : _b.pages.length;
if (!pageCount)
return list;
const lastPage = (_c = feedQuery.data) === null || _c === void 0 ? void 0 : _c.pages[pageCount - 1];
list.push(...createPostPlaceholders("next", lastPage === null || lastPage === void 0 ? void 0 : lastPage.nextCount));
}
return list;
}, [
feedQuery.data,
pageContext.feedPageMeta.posts,
feedQuery.isFetchingNextPage,
]);
return {
feedElementRef,
feedListing,
};
};
exports.default = useInfiniteFeed;