UNPKG

@replyke/core

Version:

Replyke: Build interactive apps with social features like comments, votes, feeds, user lists, notifications, and more.

394 lines 20.3 kB
"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; 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 __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype); return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (g && (g = 0, op[0] && (_ = 0)), _) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); var react_1 = require("react"); var useCreateEntity_1 = __importDefault(require("./useCreateEntity")); var useFetchManyEntities_1 = __importDefault(require("./useFetchManyEntities")); var useDeleteEntity_1 = __importDefault(require("./useDeleteEntity")); var useInfusedData_1 = __importDefault(require("./useInfusedData")); var handleError_1 = require("../../utils/handleError"); function useEntityListData(_a) { var _this = this; var _b = _a.limit, limit = _b === void 0 ? 10 : _b, _c = _a.sortBy, sortByProp = _c === void 0 ? "hot" : _c, _d = _a.timeFrame, timeFrameProp = _d === void 0 ? null : _d, _e = _a.sourceId, sourceIdProp = _e === void 0 ? null : _e, _f = _a.userId, userIdProp = _f === void 0 ? null : _f, followedOnlyProp = _a.followedOnly, _g = _a.keywordsFilters, keywordsFiltersProp = _g === void 0 ? null : _g, _h = _a.locationFilters, locationFiltersProp = _h === void 0 ? null : _h, _j = _a.metadataFilters, metadataFiltersProp = _j === void 0 ? null : _j, _k = _a.titleFilters, titleFiltersProp = _k === void 0 ? null : _k, _l = _a.contentFilters, contentFiltersProp = _l === void 0 ? null : _l, _m = _a.attachmentsFilters, attachmentsFiltersProp = _m === void 0 ? null : _m, _o = _a.idle, idle = _o === void 0 ? false : _o, onReset = _a.onReset, infuseData = _a.infuseData; var _p = (0, react_1.useState)([]), entities = _p[0], setEntities = _p[1]; var _q = (0, react_1.useState)(1), page = _q[0], setPage = _q[1]; var debounceTimer = (0, react_1.useRef)(null); var _r = (0, react_1.useState)(idle), idling = _r[0], setIdling = _r[1]; var loading = (0, react_1.useRef)(true); var _s = (0, react_1.useState)(true), loadingState = _s[0], setLoadingState = _s[1]; // required to trigger rerenders var _t = (0, react_1.useState)(true), resetting = _t[0], setResetting = _t[1]; // Specifically to indicate when we're loading new entities due to a reset var hasMore = (0, react_1.useRef)(true); var _u = (0, react_1.useState)(true), hasMoreState = _u[0], setHasMoreState = _u[1]; // required to trigger rerenders var _v = (0, react_1.useState)(!!followedOnlyProp), followedOnly = _v[0], setFollowedOnly = _v[1]; var _w = (0, react_1.useState)(sortByProp), sortBy = _w[0], setSortBy = _w[1]; var _x = (0, react_1.useState)(sourceIdProp), sourceId = _x[0], setSourceId = _x[1]; var _y = (0, react_1.useState)(userIdProp), userId = _y[0], setUserId = _y[1]; var _z = (0, react_1.useState)(timeFrameProp), timeFrame = _z[0], setTimeFrame = _z[1]; var _0 = (0, react_1.useState)(keywordsFiltersProp), keywordsFilters = _0[0], setKeywordsFilters = _0[1]; var _1 = (0, react_1.useState)(metadataFiltersProp), metadataFilters = _1[0], setMetadataFilters = _1[1]; var _2 = (0, react_1.useState)(titleFiltersProp), titleFilters = _2[0], setTitleFilters = _2[1]; var _3 = (0, react_1.useState)(contentFiltersProp), contentFilters = _3[0], setContentFilters = _3[1]; var _4 = (0, react_1.useState)(attachmentsFiltersProp), attachmentsFilters = _4[0], setAttachmentsFilters = _4[1]; var _5 = (0, react_1.useState)(locationFiltersProp), locationFilters = _5[0], setLocationFilters = _5[1]; var infusedEntities = (0, useInfusedData_1.default)({ entities: entities, infuseData: infuseData }); var fetchManyEntities = (0, useFetchManyEntities_1.default)(); var createEntity = (0, useCreateEntity_1.default)(); var deleteEntity = (0, useDeleteEntity_1.default)(); var kickstart = function () { return setIdling(false); }; /** * Updates the keywords state based on the action provided. * * @param type - The action type ('add', 'remove', 'reset'). * @param key - The keyword list to modify ('included', 'excluded'). * @param value - The value(s) to add or remove (optional). */ var updateKeywordsFilters = function (type, key, value) { var items = Array.isArray(value) ? value : value ? [value] : []; setKeywordsFilters(function (prev) { var _a, _b, _c, _d; if (!prev) prev = {}; switch (type) { case "add": { if (key === "both") return prev; // Invalid to add to both return __assign(__assign({}, prev), (_a = {}, _a[key] = Array.from(new Set(__spreadArray(__spreadArray([], (prev[key] || []), true), items, true))), _a)); } case "remove": { if (key === "both") { return { includes: (prev.includes || []).filter(function (item) { return !items.includes(item); }), doesNotInclude: (prev.doesNotInclude || []).filter(function (item) { return !items.includes(item); }), }; } return __assign(__assign({}, prev), (_b = {}, _b[key] = (prev[key] || []).filter(function (item) { return !items.includes(item); }), _b)); } case "reset": { if (key === "both") return null; // Resets everything return __assign(__assign({}, prev), (_c = {}, _c[key] = undefined, _c)); } case "replace": { if (key === "both") return prev; // Replace does not apply to both return __assign(__assign({}, prev), (_d = {}, _d[key] = items, _d)); } default: return prev; } }); }; var handleCreateEntity = (0, react_1.useCallback)(function (_a) { return __awaiter(_this, void 0, void 0, function () { var newEntity_1, err_1; var insertPosition = _a.insertPosition, restOfProps = __rest(_a, ["insertPosition"]); return __generator(this, function (_b) { switch (_b.label) { case 0: _b.trys.push([0, 2, , 3]); return [4 /*yield*/, createEntity(restOfProps)]; case 1: newEntity_1 = _b.sent(); if (insertPosition === "last") { setEntities === null || setEntities === void 0 ? void 0 : setEntities(function (prevEntities) { return __spreadArray(__spreadArray([], prevEntities, true), [newEntity_1], false); }); } else { setEntities === null || setEntities === void 0 ? void 0 : setEntities(function (prevEntities) { return __spreadArray([newEntity_1], prevEntities, true); }); } return [2 /*return*/, newEntity_1]; case 2: err_1 = _b.sent(); (0, handleError_1.handleError)(err_1, "Failed to create entity"); return [3 /*break*/, 3]; case 3: return [2 /*return*/]; } }); }); }, [createEntity]); var handleDeleteEntity = (0, react_1.useCallback)(function (_a) { return __awaiter(_this, [_a], void 0, function (_b) { var err_2; var entityId = _b.entityId; return __generator(this, function (_c) { switch (_c.label) { case 0: _c.trys.push([0, 2, , 3]); return [4 /*yield*/, deleteEntity({ entityId: entityId })]; case 1: _c.sent(); setEntities(function (prev) { return prev.filter(function (e) { return e.id !== entityId; }); }); return [3 /*break*/, 3]; case 2: err_2 = _c.sent(); (0, handleError_1.handleError)(err_2, "Failed to delete entity"); return [3 /*break*/, 3]; case 3: return [2 /*return*/]; } }); }); }, [deleteEntity]); var resetEntities = (0, react_1.useCallback)(function () { return __awaiter(_this, void 0, void 0, function () { var newEntities, err_3; return __generator(this, function (_a) { switch (_a.label) { case 0: if (idling) return [2 /*return*/]; loading.current = true; setLoadingState(true); setResetting(true); hasMore.current = true; setHasMoreState(true); setPage(1); _a.label = 1; case 1: _a.trys.push([1, 3, 4, 5]); return [4 /*yield*/, fetchManyEntities({ page: 1, sortBy: sortBy, timeFrame: timeFrame, userId: userId, sourceId: sourceId, followedOnly: followedOnly, limit: limit, locationFilters: locationFilters, keywordsFilters: keywordsFilters, metadataFilters: metadataFilters, titleFilters: titleFilters, contentFilters: contentFilters, attachmentsFilters: attachmentsFilters, })]; case 2: newEntities = _a.sent(); if (newEntities) { setEntities(newEntities); if (newEntities.length < limit) { hasMore.current = false; setHasMoreState(false); } } return [3 /*break*/, 5]; case 3: err_3 = _a.sent(); (0, handleError_1.handleError)(err_3, "Failed to reset entities:"); return [3 /*break*/, 5]; case 4: loading.current = false; setLoadingState(false); setResetting(false); return [7 /*endfinally*/]; case 5: return [2 /*return*/]; } }); }); }, [ idling, fetchManyEntities, limit, sourceId, userId, followedOnly, sortBy, timeFrame, locationFilters, keywordsFilters, metadataFilters, titleFilters, contentFilters, attachmentsFilters, ]); var loadMore = function () { if (loading.current || !hasMore.current) return; setPage(function (prevPage) { return prevPage + 1; }); }; var filterEntities = function (newEntities, currentEntities) { return newEntities.filter(function (entity) { return !currentEntities.some(function (a) { return a.id === entity.id; }); }); }; (0, react_1.useEffect)(function () { if (debounceTimer.current) { clearTimeout(debounceTimer.current); } debounceTimer.current = setTimeout(function () { onReset === null || onReset === void 0 ? void 0 : onReset(); resetEntities(); }, 800); // 800ms debounce delay return function () { if (debounceTimer.current) { clearTimeout(debounceTimer.current); } }; }, [resetEntities, onReset]); // useEffect to get a new batch of entities (0, react_1.useEffect)(function () { var loadMoreEntities = function () { return __awaiter(_this, void 0, void 0, function () { var newEntities_1, err_4; return __generator(this, function (_a) { switch (_a.label) { case 0: loading.current = true; setLoadingState(true); _a.label = 1; case 1: _a.trys.push([1, 3, 4, 5]); return [4 /*yield*/, fetchManyEntities({ page: page, userId: userId, sourceId: sourceId, followedOnly: followedOnly, sortBy: sortBy, limit: limit, timeFrame: timeFrame, locationFilters: locationFilters, keywordsFilters: keywordsFilters, metadataFilters: metadataFilters, titleFilters: titleFilters, contentFilters: contentFilters, attachmentsFilters: attachmentsFilters, })]; case 2: newEntities_1 = _a.sent(); if (newEntities_1) { setEntities(function (prevEntities) { var filteredEntities = filterEntities(newEntities_1, prevEntities); return __spreadArray(__spreadArray([], prevEntities, true), filteredEntities, true); }); if (newEntities_1.length < limit) { hasMore.current = false; setHasMoreState(false); } } return [3 /*break*/, 5]; case 3: err_4 = _a.sent(); (0, handleError_1.handleError)(err_4, "Loading more entities failed:"); return [3 /*break*/, 5]; case 4: loading.current = false; setLoadingState(false); return [7 /*endfinally*/]; case 5: return [2 /*return*/]; } }); }); }; // We only load more if th page changed if (page > 1 && hasMore.current && !loading.current) { loadMoreEntities(); } }, [page]); return { entities: entities, setEntities: setEntities, infusedEntities: infusedEntities, loading: loadingState, hasMore: hasMoreState, resetting: resetting, sortBy: sortBy, setSortBy: function (sortBy) { return setSortBy(sortBy); }, timeFrame: timeFrame, setTimeFrame: function (timeFrame) { return setTimeFrame(timeFrame); }, sourceId: sourceId, setSourceId: setSourceId, userId: userId, setUserId: function (userId) { return setUserId(userId); }, followedOnly: followedOnly, setFollowedOnly: function (state) { return setFollowedOnly(state); }, keywordsFilters: keywordsFilters, updateKeywordsFilters: updateKeywordsFilters, titleFilters: titleFilters, setTitleFilters: function (newTitleFilters) { return setTitleFilters(newTitleFilters); }, contentFilters: contentFilters, setContentFilters: function (newContentFilters) { return setContentFilters(newContentFilters); }, attachmentsFilters: attachmentsFilters, setAttachmentsFilters: function (newAttachmentsFilters) { return setAttachmentsFilters(newAttachmentsFilters); }, locationFilters: locationFilters, setLocationFilters: function (location) { return setLocationFilters(location); }, metadataFilters: metadataFilters, setMetadataFilters: function (newMetadataFilters) { return setMetadataFilters(newMetadataFilters); }, kickstart: kickstart, loadMore: loadMore, resetEntities: resetEntities, createEntity: handleCreateEntity, deleteEntity: handleDeleteEntity, }; } exports.default = useEntityListData; //# sourceMappingURL=useEntityListData.js.map