@gravity-ui/blog-constructor 4.0.0-alpha.1 → 4.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/build/cjs/blocks/Feed/Feed.js +47 -37
  3. package/build/cjs/blocks/Feed/reducer.d.ts +0 -5
  4. package/build/cjs/blocks/Feed/reducer.js +1 -4
  5. package/build/cjs/blocks/Header/schema.d.ts +81 -0
  6. package/build/cjs/blocks/Media/schema.d.ts +81 -0
  7. package/build/cjs/blocks/YFM/YFM.js +1 -1
  8. package/build/cjs/components/FeedHeader/FeedHeader.js +2 -2
  9. package/build/cjs/components/FeedHeader/components/Controls/Controls.d.ts +2 -3
  10. package/build/cjs/components/FeedHeader/components/Controls/Controls.js +24 -16
  11. package/build/cjs/components/Paginator/Paginator.d.ts +1 -1
  12. package/build/cjs/components/Paginator/Paginator.js +2 -2
  13. package/build/cjs/components/Paginator/types.d.ts +0 -1
  14. package/build/cjs/components/PostInfo/components/Save.js +6 -1
  15. package/build/cjs/components/Posts/Posts.css +25 -0
  16. package/build/cjs/components/Posts/Posts.d.ts +0 -1
  17. package/build/cjs/components/Posts/Posts.js +5 -4
  18. package/build/cjs/components/Prompt/Prompt.css +61 -0
  19. package/build/cjs/components/Prompt/Prompt.d.ts +17 -0
  20. package/build/cjs/components/Prompt/Prompt.js +41 -0
  21. package/build/cjs/components/PromptSignIn/PromptSignIn.d.ts +10 -0
  22. package/build/cjs/components/PromptSignIn/PromptSignIn.js +35 -0
  23. package/build/cjs/components/PromptSignIn/hooks/usePromptSignInProps.d.ts +6 -0
  24. package/build/cjs/components/PromptSignIn/hooks/usePromptSignInProps.js +16 -0
  25. package/build/cjs/components/Search/Search.js +1 -1
  26. package/build/cjs/containers/BlogPage/BlogPage.d.ts +4 -1
  27. package/build/cjs/containers/BlogPage/BlogPage.js +56 -18
  28. package/build/cjs/contexts/LikesContext.d.ts +2 -0
  29. package/build/cjs/hooks/useOpenCloseTimer.d.ts +9 -0
  30. package/build/cjs/hooks/useOpenCloseTimer.js +30 -0
  31. package/build/cjs/i18n/index.d.ts +3 -1
  32. package/build/cjs/i18n/index.js +6 -0
  33. package/build/cjs/models/common.d.ts +5 -1
  34. package/build/cjs/schema/index.d.ts +162 -0
  35. package/build/cjs/utils/common.js +1 -1
  36. package/build/esm/blocks/Feed/Feed.js +47 -37
  37. package/build/esm/blocks/Feed/reducer.d.ts +0 -5
  38. package/build/esm/blocks/Feed/reducer.js +1 -4
  39. package/build/esm/blocks/Header/schema.d.ts +81 -0
  40. package/build/esm/blocks/Media/schema.d.ts +81 -0
  41. package/build/esm/blocks/YFM/YFM.js +1 -1
  42. package/build/esm/components/FeedHeader/FeedHeader.js +2 -2
  43. package/build/esm/components/FeedHeader/components/Controls/Controls.d.ts +2 -3
  44. package/build/esm/components/FeedHeader/components/Controls/Controls.js +25 -17
  45. package/build/esm/components/Paginator/Paginator.d.ts +1 -1
  46. package/build/esm/components/Paginator/Paginator.js +2 -2
  47. package/build/esm/components/Paginator/types.d.ts +0 -1
  48. package/build/esm/components/PostInfo/components/Save.js +6 -1
  49. package/build/esm/components/Posts/Posts.css +25 -0
  50. package/build/esm/components/Posts/Posts.d.ts +0 -1
  51. package/build/esm/components/Posts/Posts.js +5 -4
  52. package/build/esm/components/Prompt/Prompt.css +61 -0
  53. package/build/esm/components/Prompt/Prompt.d.ts +18 -0
  54. package/build/esm/components/Prompt/Prompt.js +35 -0
  55. package/build/esm/components/PromptSignIn/PromptSignIn.d.ts +10 -0
  56. package/build/esm/components/PromptSignIn/PromptSignIn.js +28 -0
  57. package/build/esm/components/PromptSignIn/hooks/usePromptSignInProps.d.ts +6 -0
  58. package/build/esm/components/PromptSignIn/hooks/usePromptSignInProps.js +12 -0
  59. package/build/esm/components/Search/Search.js +1 -1
  60. package/build/esm/containers/BlogPage/BlogPage.d.ts +4 -1
  61. package/build/esm/containers/BlogPage/BlogPage.js +33 -18
  62. package/build/esm/contexts/LikesContext.d.ts +2 -0
  63. package/build/esm/hooks/useOpenCloseTimer.d.ts +9 -0
  64. package/build/esm/hooks/useOpenCloseTimer.js +26 -0
  65. package/build/esm/i18n/index.d.ts +3 -1
  66. package/build/esm/i18n/index.js +6 -0
  67. package/build/esm/models/common.d.ts +5 -1
  68. package/build/esm/schema/index.d.ts +162 -0
  69. package/build/esm/utils/common.js +1 -1
  70. package/package.json +3 -6
  71. package/server/data/sanitizeMeta.d.ts +2 -0
  72. package/server/data/sanitizeMeta.js +2 -0
  73. package/server/data/transformPageContent.js +1 -1
  74. package/server/models/common.d.ts +5 -1
  75. package/build/cjs/blocks/YFM/__tests__/YFM.test.d.ts +0 -1
  76. package/build/cjs/blocks/YFM/__tests__/YFM.test.js +0 -16
  77. package/build/esm/blocks/YFM/__tests__/YFM.test.d.ts +0 -1
  78. package/build/esm/blocks/YFM/__tests__/YFM.test.js +0 -11
@@ -13,8 +13,9 @@ const Paginator_1 = require("../Paginator/Paginator");
13
13
  const PostCard_1 = require("../PostCard/PostCard");
14
14
  const PostsEmpty_1 = require("../PostsEmpty/PostsEmpty");
15
15
  const b = (0, cn_1.block)('posts');
16
- const Posts = ({ containerId, pinnedPostOnPage, currentPage, postsOnPage, isShowMoreVisible, errorShowMore, postCountOnPage, perPageInQuery, isFetching, isShowMoreFetching, handleShowMore, handlePageChange, pageCountForShowSupportButtons, }) => (react_1.default.createElement("div", { className: b() },
17
- react_1.default.createElement("div", { id: containerId, className: b('cards-container') },
16
+ const Posts = ({ containerId, pinnedPostOnPage, currentPage, postsOnPage, isShowMoreVisible, errorShowMore, postCountOnPage, perPageInQuery, isFetching, handleShowMore, handlePageChange, pageCountForShowSupportButtons, }) => (react_1.default.createElement("div", { className: b() },
17
+ isFetching && react_1.default.createElement("div", { className: b('loaderContainer') }),
18
+ react_1.default.createElement("div", { id: containerId, className: b('cards-container', { isLoading: isFetching }) },
18
19
  pinnedPostOnPage && currentPage === 1 && (react_1.default.createElement("div", { className: b('pinned-container') },
19
20
  react_1.default.createElement(PostCard_1.PostCard, { post: pinnedPostOnPage, size: "m", fullWidth: true, showTag: true }))),
20
21
  (postsOnPage === null || postsOnPage === void 0 ? void 0 : postsOnPage.length) ? (react_1.default.createElement(page_constructor_1.CardLayoutBlock, { title: '', colSizes: {
@@ -23,10 +24,10 @@ const Posts = ({ containerId, pinnedPostOnPage, currentPage, postsOnPage, isShow
23
24
  md: 6,
24
25
  } }, postsOnPage === null || postsOnPage === void 0 ? void 0 : postsOnPage.map((post) => (react_1.default.createElement(PostCard_1.PostCard, { key: post.id, post: post, showTag: true }))))) : (react_1.default.createElement(PostsEmpty_1.PostsEmpty, null))),
25
26
  react_1.default.createElement("div", { className: b('pagination') },
26
- Boolean(isShowMoreVisible && (postsOnPage === null || postsOnPage === void 0 ? void 0 : postsOnPage.length)) && (react_1.default.createElement(uikit_1.Button, { view: "outlined", size: "xl", className: b('more-button'), onClick: handleShowMore, loading: isShowMoreFetching }, (0, i18n_1.i18)(i18n_1.Keyset.ActionLoadMore))),
27
+ Boolean(isShowMoreVisible && (postsOnPage === null || postsOnPage === void 0 ? void 0 : postsOnPage.length)) && (react_1.default.createElement(uikit_1.Button, { view: "outlined", size: "xl", className: b('more-button'), onClick: handleShowMore }, (0, i18n_1.i18)(i18n_1.Keyset.ActionLoadMore))),
27
28
  errorShowMore && (react_1.default.createElement("div", { className: b('error-show-more') },
28
29
  react_1.default.createElement("div", null, (0, i18n_1.i18)(i18n_1.Keyset.ErrorTitle)),
29
30
  react_1.default.createElement("div", null, (0, i18n_1.i18)(i18n_1.Keyset.PostLoadError)))),
30
31
  Boolean(currentPage && postCountOnPage) && (react_1.default.createElement("div", { className: b('paginator') },
31
- react_1.default.createElement(Paginator_1.Paginator, { onPageChange: handlePageChange, page: currentPage, totalItems: postCountOnPage, itemsPerPage: perPageInQuery, loading: isFetching, maxPages: Infinity, pageCountForShowSupportButtons: pageCountForShowSupportButtons }))))));
32
+ react_1.default.createElement(Paginator_1.Paginator, { onPageChange: handlePageChange, page: currentPage, totalItems: postCountOnPage, itemsPerPage: perPageInQuery, maxPages: Infinity, pageCountForShowSupportButtons: pageCountForShowSupportButtons }))))));
32
33
  exports.Posts = Posts;
@@ -0,0 +1,61 @@
1
+ .bc-prompt__content {
2
+ box-shadow: 0px 4px 24px var(--pc-color-sfx-shadow), 0px 2px 8px var(--pc-color-sfx-shadow);
3
+ }
4
+
5
+ /* use this for style redefinitions to awoid problems with
6
+ unpredictable css rules order in build */
7
+ @keyframes bc-prompt_open {
8
+ 0% {
9
+ opacity: 0;
10
+ transform: translateY(100%);
11
+ }
12
+ 100% {
13
+ opacity: 1;
14
+ transform: translateY(0%);
15
+ }
16
+ }
17
+ @keyframes bc-prompt_close {
18
+ 0% {
19
+ opacity: 1;
20
+ transform: translateY(0%);
21
+ }
22
+ 100% {
23
+ opacity: 0;
24
+ transform: translateY(100%);
25
+ }
26
+ }
27
+ .bc-prompt {
28
+ display: flex;
29
+ width: 100%;
30
+ justify-content: center;
31
+ overflow: hidden;
32
+ position: fixed;
33
+ bottom: 0;
34
+ }
35
+ .bc-prompt:not(.bc-prompt_mounted) {
36
+ display: none;
37
+ }
38
+ .bc-prompt__content {
39
+ display: flex;
40
+ flex-flow: row wrap;
41
+ gap: 16px;
42
+ align-items: center;
43
+ margin: 24px;
44
+ padding: 16px 20px;
45
+ border-radius: calc(var(--pc-border-radius) / 2);
46
+ background-color: var(--yc-color-base-float);
47
+ font-size: var(--yc-text-body-2-font-size);
48
+ }
49
+ .bc-prompt_close {
50
+ pointer-events: none;
51
+ }
52
+ .bc-prompt_open > .bc-prompt__content {
53
+ opacity: 0;
54
+ transform: translateY(100%);
55
+ animation: bc-prompt_open 600ms forwards;
56
+ }
57
+ .bc-prompt_close > .bc-prompt__content {
58
+ opacity: 1;
59
+ transform: translateY(0%);
60
+ animation: bc-prompt_close 600ms forwards;
61
+ }
@@ -0,0 +1,17 @@
1
+ import { ButtonProps } from '@gravity-ui/uikit';
2
+ export interface PromptProps {
3
+ text: string;
4
+ actions: ButtonProps[];
5
+ openTimestamp?: number;
6
+ openDuration?: number;
7
+ className?: string;
8
+ theme?: 'grey' | 'beige' | 'white';
9
+ }
10
+ /**
11
+ * Popup that appears with text message and button(s) for given `actions`.
12
+ * Features:
13
+ * - Automatically disappears after `openDuration` in milliseconds
14
+ * - `openTimestamp` (`Date.now()`) resets the visible duration
15
+ * @returns {JSX|null}
16
+ */
17
+ export declare const Prompt: ({ text, actions, className, openTimestamp, openDuration, theme, }: PromptProps) => JSX.Element;
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.Prompt = void 0;
18
+ const react_1 = __importDefault(require("react"));
19
+ const uikit_1 = require("@gravity-ui/uikit");
20
+ const useOpenCloseTimer_1 = require("../../hooks/useOpenCloseTimer");
21
+ const cn_1 = require("../../utils/cn");
22
+ const b = (0, cn_1.block)('prompt');
23
+ /**
24
+ * Popup that appears with text message and button(s) for given `actions`.
25
+ * Features:
26
+ * - Automatically disappears after `openDuration` in milliseconds
27
+ * - `openTimestamp` (`Date.now()`) resets the visible duration
28
+ * @returns {JSX|null}
29
+ */
30
+ const Prompt = ({ text, actions, className, openTimestamp = 0, openDuration, theme, }) => {
31
+ const { open } = (0, useOpenCloseTimer_1.useOpenCloseTimer)(openTimestamp, openDuration);
32
+ const mounted = openTimestamp > 0;
33
+ return (react_1.default.createElement("div", { className: b({ theme, open, close: !open, mounted }, className) },
34
+ react_1.default.createElement("div", { className: b('content') },
35
+ react_1.default.createElement("span", { className: b('text') }, text),
36
+ react_1.default.createElement("div", { className: b('actions') }, actions.map((_a, i) => {
37
+ var { view = 'action', className: btnClass } = _a, btnProps = __rest(_a, ["view", "className"]);
38
+ return (react_1.default.createElement(uikit_1.Button, Object.assign({ key: i, className: b('action', btnClass), view: view }, btnProps)));
39
+ })))));
40
+ };
41
+ exports.Prompt = Prompt;
@@ -0,0 +1,10 @@
1
+ import React, { SyntheticEvent } from 'react';
2
+ import { PromptProps } from '../Prompt/Prompt';
3
+ export interface PromptSignInProps extends Partial<PromptProps> {
4
+ onClickSignIn?: React.EventHandler<SyntheticEvent>;
5
+ }
6
+ /**
7
+ * Authentication Popup that appears when user action requires login
8
+ * @returns {JSX|null}
9
+ */
10
+ export declare const PromptSignIn: ({ text, onClickSignIn, actions, ...props }: PromptSignInProps) => JSX.Element;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.PromptSignIn = void 0;
18
+ const react_1 = __importDefault(require("react"));
19
+ const i18n_1 = require("../../i18n");
20
+ const Prompt_1 = require("../Prompt/Prompt");
21
+ /**
22
+ * Authentication Popup that appears when user action requires login
23
+ * @returns {JSX|null}
24
+ */
25
+ const PromptSignIn = (_a) => {
26
+ var { text = (0, i18n_1.i18)(i18n_1.Keyset.PromptSignInOnLike), onClickSignIn = () => alert((0, i18n_1.i18)(i18n_1.Keyset.SignIn)), actions = [
27
+ {
28
+ children: (0, i18n_1.i18)(i18n_1.Keyset.SignIn),
29
+ onClick: onClickSignIn,
30
+ size: 'l',
31
+ },
32
+ ] } = _a, props = __rest(_a, ["text", "onClickSignIn", "actions"]);
33
+ return react_1.default.createElement(Prompt_1.Prompt, Object.assign({}, { text, actions }, props));
34
+ };
35
+ exports.PromptSignIn = PromptSignIn;
@@ -0,0 +1,6 @@
1
+ import React, { SyntheticEvent } from 'react';
2
+ export declare function usePromptSignInProps(onClickSignIn?: React.EventHandler<SyntheticEvent>): {
3
+ onClickSignIn: ((event: React.SyntheticEvent<Element, Event>) => void) | undefined;
4
+ openTimestamp: number;
5
+ requireSignIn: (() => void) | undefined;
6
+ };
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.usePromptSignInProps = void 0;
4
+ const react_1 = require("react");
5
+ function usePromptSignInProps(onClickSignIn) {
6
+ const [openTimestamp, setTime] = (0, react_1.useState)(0);
7
+ const requireSignIn = (0, react_1.useMemo)(() => {
8
+ return onClickSignIn
9
+ ? () => {
10
+ setTime(Date.now());
11
+ }
12
+ : undefined;
13
+ }, [onClickSignIn, setTime]);
14
+ return { onClickSignIn, openTimestamp, requireSignIn };
15
+ }
16
+ exports.usePromptSignInProps = usePromptSignInProps;
@@ -25,8 +25,8 @@ var __importStar = (this && this.__importStar) || function (mod) {
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.Search = void 0;
27
27
  const react_1 = __importStar(require("react"));
28
- const lodash_1 = require("lodash");
29
28
  const uikit_1 = require("@gravity-ui/uikit");
29
+ const lodash_1 = require("lodash");
30
30
  const useIsIPhone_1 = require("../../hooks/useIsIPhone");
31
31
  const i18n_1 = require("../../i18n");
32
32
  const Close_1 = require("../../icons/Close");
@@ -1,3 +1,4 @@
1
+ import React, { SyntheticEvent } from 'react';
1
2
  import { NavigationData, PageConstructorProviderProps, PageContent } from '@gravity-ui/page-constructor';
2
3
  import { GetPostsType, MetaProps, PostsProps, Service, SetQueryType, Tag, ToggleLikeCallbackType } from '../../models/common';
3
4
  export type BlogPageProps = {
@@ -13,5 +14,7 @@ export type BlogPageProps = {
13
14
  setQuery?: SetQueryType;
14
15
  settings?: PageConstructorProviderProps;
15
16
  pageCountForShowSupportButtons?: number;
17
+ isSignedInUser?: boolean;
18
+ onClickSignIn?: React.EventHandler<SyntheticEvent>;
16
19
  };
17
- export declare const BlogPage: ({ content, posts, tags, services, getPosts, metaData, hasLikes, toggleLike, navigation, settings, pageCountForShowSupportButtons, }: BlogPageProps) => JSX.Element;
20
+ export declare const BlogPage: ({ content, posts, tags, services, getPosts, metaData, hasLikes, toggleLike, navigation, settings, pageCountForShowSupportButtons, isSignedInUser, onClickSignIn, }: BlogPageProps) => JSX.Element;
@@ -1,30 +1,68 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __rest = (this && this.__rest) || function (s, e) {
26
+ var t = {};
27
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
28
+ t[p] = s[p];
29
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
30
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
31
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
32
+ t[p[i]] = s[p[i]];
33
+ }
34
+ return t;
35
+ };
2
36
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
37
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
38
  };
5
39
  Object.defineProperty(exports, "__esModule", { value: true });
6
40
  exports.BlogPage = void 0;
7
- const react_1 = __importDefault(require("react"));
41
+ const react_1 = __importStar(require("react"));
8
42
  const page_constructor_1 = require("@gravity-ui/page-constructor");
9
43
  const MetaWrapper_1 = require("../../components/MetaWrapper/MetaWrapper");
44
+ const PromptSignIn_1 = require("../../components/PromptSignIn/PromptSignIn");
45
+ const usePromptSignInProps_1 = require("../../components/PromptSignIn/hooks/usePromptSignInProps");
10
46
  const blocksMap_1 = __importDefault(require("../../constructor/blocksMap"));
11
47
  const FeedContext_1 = require("../../contexts/FeedContext");
12
48
  const LikesContext_1 = require("../../contexts/LikesContext");
13
- const BlogPage = ({ content, posts, tags, services, getPosts, metaData, hasLikes = false, toggleLike, navigation, settings, pageCountForShowSupportButtons, }) => (react_1.default.createElement("main", null,
14
- react_1.default.createElement(LikesContext_1.LikesContext.Provider, { value: {
15
- toggleLike: toggleLike,
16
- hasLikes,
17
- } },
18
- react_1.default.createElement(FeedContext_1.FeedContext.Provider, { value: {
19
- posts: posts.posts,
20
- pinnedPost: posts.pinnedPost,
21
- totalCount: posts.count,
22
- tags,
23
- services: services !== null && services !== void 0 ? services : [],
24
- getPosts,
25
- pageCountForShowSupportButtons,
26
- } },
27
- react_1.default.createElement(page_constructor_1.PageConstructorProvider, Object.assign({}, settings),
28
- metaData ? react_1.default.createElement(MetaWrapper_1.MetaWrapper, Object.assign({}, metaData)) : null,
29
- react_1.default.createElement(page_constructor_1.PageConstructor, { content: content, custom: blocksMap_1.default, navigation: navigation }))))));
49
+ const BlogPage = ({ content, posts, tags, services, getPosts, metaData, hasLikes = false, toggleLike, navigation, settings, pageCountForShowSupportButtons, isSignedInUser = false, onClickSignIn, }) => {
50
+ const _a = (0, usePromptSignInProps_1.usePromptSignInProps)(onClickSignIn), { requireSignIn } = _a, promptSignInProps = __rest(_a, ["requireSignIn"]);
51
+ const likes = (0, react_1.useMemo)(() => ({ toggleLike, hasLikes, isSignedInUser, requireSignIn }), [toggleLike, hasLikes, isSignedInUser, requireSignIn]);
52
+ return (react_1.default.createElement("main", null,
53
+ react_1.default.createElement(LikesContext_1.LikesContext.Provider, { value: likes },
54
+ react_1.default.createElement(FeedContext_1.FeedContext.Provider, { value: {
55
+ posts: posts.posts,
56
+ pinnedPost: posts.pinnedPost,
57
+ totalCount: posts.count,
58
+ tags,
59
+ services: services !== null && services !== void 0 ? services : [],
60
+ getPosts,
61
+ pageCountForShowSupportButtons,
62
+ } },
63
+ react_1.default.createElement(page_constructor_1.PageConstructorProvider, Object.assign({}, settings),
64
+ metaData ? react_1.default.createElement(MetaWrapper_1.MetaWrapper, Object.assign({}, metaData)) : null,
65
+ react_1.default.createElement(page_constructor_1.PageConstructor, { content: content, custom: blocksMap_1.default, navigation: navigation })))),
66
+ react_1.default.createElement(PromptSignIn_1.PromptSignIn, Object.assign({}, promptSignInProps))));
67
+ };
30
68
  exports.BlogPage = BlogPage;
@@ -3,5 +3,7 @@ import { ToggleLikeCallbackType } from '../models/common';
3
3
  export interface LikesContextProps {
4
4
  toggleLike?: ToggleLikeCallbackType;
5
5
  hasLikes?: boolean;
6
+ isSignedInUser?: boolean;
7
+ requireSignIn?: React.MouseEventHandler;
6
8
  }
7
9
  export declare const LikesContext: React.Context<LikesContextProps>;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Timer to automatically update `open` state after a given duration
3
+ * @param {number} openTimestamp - UNIX timestamp in milliseconds
4
+ * @param {number} openDuration - in milliseconds
5
+ * @returns {{open: boolean}} {open} - whether the state is open
6
+ */
7
+ export declare function useOpenCloseTimer(openTimestamp?: number, openDuration?: number): {
8
+ open: boolean;
9
+ };
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useOpenCloseTimer = void 0;
4
+ const react_1 = require("react");
5
+ /**
6
+ * Timer to automatically update `open` state after a given duration
7
+ * @param {number} openTimestamp - UNIX timestamp in milliseconds
8
+ * @param {number} openDuration - in milliseconds
9
+ * @returns {{open: boolean}} {open} - whether the state is open
10
+ */
11
+ function useOpenCloseTimer(openTimestamp = Date.now(), openDuration = 4000) {
12
+ const open = Date.now() - openTimestamp < openDuration;
13
+ const [, reset] = (0, react_1.useState)(0); // time to reset `open` state
14
+ (0, react_1.useEffect)(() => {
15
+ const closeTime = openTimestamp + openDuration;
16
+ const delay = closeTime - Date.now();
17
+ if (delay <= 0) {
18
+ return;
19
+ }
20
+ const timer = setTimeout(() => {
21
+ reset(Date.now);
22
+ }, delay);
23
+ // eslint-disable-next-line consistent-return
24
+ return () => {
25
+ clearTimeout(timer);
26
+ };
27
+ }, [openTimestamp, openDuration]);
28
+ return { open };
29
+ }
30
+ exports.useOpenCloseTimer = useOpenCloseTimer;
@@ -17,6 +17,8 @@ export declare enum Keyset {
17
17
  Search = "search_placeholder",
18
18
  AllTags = "label_all_tags",
19
19
  ActionSavedOnly = "action_saved_only",
20
- AllServices = "label_all_services"
20
+ AllServices = "label_all_services",
21
+ PromptSignInOnLike = "prompt_sign_in_on_like",
22
+ SignIn = "Sign In"
21
23
  }
22
24
  export declare const i18: (key: string, params?: import("@gravity-ui/i18n").Params | undefined) => string;
@@ -24,6 +24,8 @@ var Keyset;
24
24
  Keyset["AllTags"] = "label_all_tags";
25
25
  Keyset["ActionSavedOnly"] = "action_saved_only";
26
26
  Keyset["AllServices"] = "label_all_services";
27
+ Keyset["PromptSignInOnLike"] = "prompt_sign_in_on_like";
28
+ Keyset["SignIn"] = "Sign In";
27
29
  })(Keyset = exports.Keyset || (exports.Keyset = {}));
28
30
  exports.i18n.registerKeyset(locale_1.Lang.En, KEYSET_NAME, {
29
31
  [Keyset.Title]: 'Blog',
@@ -42,11 +44,13 @@ exports.i18n.registerKeyset(locale_1.Lang.En, KEYSET_NAME, {
42
44
  [Keyset.AllTags]: 'All topics',
43
45
  [Keyset.ActionSavedOnly]: 'Saved',
44
46
  [Keyset.AllServices]: 'All Services',
47
+ [Keyset.PromptSignInOnLike]: 'Please sign in to save your bookmarks',
45
48
  [Keyset.ContextReadingTime]: [
46
49
  '{{count}} min to read',
47
50
  '{{count}} mins to read',
48
51
  '{{count}} mins to read',
49
52
  ],
53
+ [Keyset.SignIn]: 'Sign In',
50
54
  });
51
55
  exports.i18n.registerKeyset(locale_1.Lang.Ru, KEYSET_NAME, {
52
56
  [Keyset.Title]: 'Блог',
@@ -65,10 +69,12 @@ exports.i18n.registerKeyset(locale_1.Lang.Ru, KEYSET_NAME, {
65
69
  [Keyset.AllTags]: 'Все темы',
66
70
  [Keyset.ActionSavedOnly]: 'Сохранённые',
67
71
  [Keyset.AllServices]: 'Все сервисы',
72
+ [Keyset.PromptSignInOnLike]: 'Войдите, чтобы добавить доклад в своё расписание',
68
73
  [Keyset.ContextReadingTime]: [
69
74
  '{{count}} минута чтения',
70
75
  '{{count}} минуты чтения',
71
76
  '{{count}} минут чтения',
72
77
  ],
78
+ [Keyset.SignIn]: 'Войти',
73
79
  });
74
80
  exports.i18 = exports.i18n.keyset(KEYSET_NAME);
@@ -1,6 +1,6 @@
1
1
  import { ReactNode } from 'react';
2
- import { IBrowser, IDevice } from 'ua-parser-js';
3
2
  import { HeaderBlockProps as PageConstructorHeaderBlockProps } from '@gravity-ui/page-constructor';
3
+ import { IBrowser, IDevice } from 'ua-parser-js';
4
4
  import { Locale } from '../models/locale';
5
5
  export declare enum Theme {
6
6
  Light = "light",
@@ -161,3 +161,7 @@ export declare enum DefaultEventNames {
161
161
  Service = "selector-service-click",
162
162
  SaveOnly = "save-only-button-click"
163
163
  }
164
+ export type FetchArgs = {
165
+ page?: number;
166
+ query: Query;
167
+ };
@@ -295,6 +295,87 @@ export declare const schemasForCustom: {
295
295
  type: string;
296
296
  })[];
297
297
  };
298
+ fullscreen: {
299
+ type: string;
300
+ };
301
+ analyticsEvents: {
302
+ anyOf: ({
303
+ type: string;
304
+ additionalProperties: {
305
+ type: string;
306
+ };
307
+ required: string[];
308
+ properties: {
309
+ name: {
310
+ type: string;
311
+ };
312
+ type: {
313
+ type: string;
314
+ };
315
+ counters: {
316
+ type: string;
317
+ additionalProperties: boolean;
318
+ required: never[];
319
+ properties: {
320
+ include: {
321
+ type: string;
322
+ items: {
323
+ type: string;
324
+ };
325
+ };
326
+ exclude: {
327
+ type: string;
328
+ items: {
329
+ type: string;
330
+ };
331
+ };
332
+ };
333
+ };
334
+ context: {
335
+ type: string;
336
+ };
337
+ };
338
+ } | {
339
+ type: string;
340
+ items: {
341
+ type: string;
342
+ additionalProperties: {
343
+ type: string;
344
+ };
345
+ required: string[];
346
+ properties: {
347
+ name: {
348
+ type: string;
349
+ };
350
+ type: {
351
+ type: string;
352
+ };
353
+ counters: {
354
+ type: string;
355
+ additionalProperties: boolean;
356
+ required: never[];
357
+ properties: {
358
+ include: {
359
+ type: string;
360
+ items: {
361
+ type: string;
362
+ };
363
+ };
364
+ exclude: {
365
+ type: string;
366
+ items: {
367
+ type: string;
368
+ };
369
+ };
370
+ };
371
+ };
372
+ context: {
373
+ type: string;
374
+ };
375
+ };
376
+ };
377
+ })[];
378
+ };
298
379
  };
299
380
  } | {
300
381
  type: string;
@@ -1088,6 +1169,87 @@ export declare const schemasForCustom: {
1088
1169
  type: string;
1089
1170
  })[];
1090
1171
  };
1172
+ fullscreen: {
1173
+ type: string;
1174
+ };
1175
+ analyticsEvents: {
1176
+ anyOf: ({
1177
+ type: string;
1178
+ additionalProperties: {
1179
+ type: string;
1180
+ };
1181
+ required: string[];
1182
+ properties: {
1183
+ name: {
1184
+ type: string;
1185
+ };
1186
+ type: {
1187
+ type: string;
1188
+ };
1189
+ counters: {
1190
+ type: string;
1191
+ additionalProperties: boolean;
1192
+ required: never[];
1193
+ properties: {
1194
+ include: {
1195
+ type: string;
1196
+ items: {
1197
+ type: string;
1198
+ };
1199
+ };
1200
+ exclude: {
1201
+ type: string;
1202
+ items: {
1203
+ type: string;
1204
+ };
1205
+ };
1206
+ };
1207
+ };
1208
+ context: {
1209
+ type: string;
1210
+ };
1211
+ };
1212
+ } | {
1213
+ type: string;
1214
+ items: {
1215
+ type: string;
1216
+ additionalProperties: {
1217
+ type: string;
1218
+ };
1219
+ required: string[];
1220
+ properties: {
1221
+ name: {
1222
+ type: string;
1223
+ };
1224
+ type: {
1225
+ type: string;
1226
+ };
1227
+ counters: {
1228
+ type: string;
1229
+ additionalProperties: boolean;
1230
+ required: never[];
1231
+ properties: {
1232
+ include: {
1233
+ type: string;
1234
+ items: {
1235
+ type: string;
1236
+ };
1237
+ };
1238
+ exclude: {
1239
+ type: string;
1240
+ items: {
1241
+ type: string;
1242
+ };
1243
+ };
1244
+ };
1245
+ };
1246
+ context: {
1247
+ type: string;
1248
+ };
1249
+ };
1250
+ };
1251
+ })[];
1252
+ };
1091
1253
  paddingTop: {
1092
1254
  type: string;
1093
1255
  enum: string[];
@@ -13,8 +13,8 @@ var __rest = (this && this.__rest) || function (s, e) {
13
13
  Object.defineProperty(exports, "__esModule", { value: true });
14
14
  exports.scrollOnPageChange = exports.getFeedQueryParams = exports.getBlogElementMetrika = exports.isMetrikaExist = exports.getBreadcrumbs = exports.getBlogPath = exports.updateContentSizes = exports.getTagFilterUrl = exports.postLikeStatus = exports.getTags = exports.scrollToHash = exports.getPageSearchParams = exports.getAbsolutePath = void 0;
15
15
  const url_1 = require("url");
16
- const lodash_1 = require("lodash");
17
16
  const page_constructor_1 = require("@gravity-ui/page-constructor");
17
+ const lodash_1 = require("lodash");
18
18
  const constants_1 = require("../blocks/constants");
19
19
  const i18n_1 = require("../i18n");
20
20
  function getAbsolutePath(router, url) {