Skip to content

Commit

Permalink
Merge pull request #1589 from ecency/feature/decks-virtual-scroll
Browse files Browse the repository at this point in the history
Feature/decks virtual scroll
  • Loading branch information
feruzm authored Apr 16, 2024
2 parents 874a1a9 + 4948892 commit 6ea7c50
Show file tree
Hide file tree
Showing 126 changed files with 125 additions and 85 deletions.
2 changes: 1 addition & 1 deletion src/common/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ const EntryPage = (props: any) => {
const PurchaseContainer = loadable(() => import("./pages/purchase"));
const PurchasePage = (props: any) => <PurchaseContainer {...props} />;

const DecksPage = loadable(() => import("./pages/decks"));
const DecksPage = loadable(() => import("./features/decks/screens/decks"));
const EcencyPerksPage = loadable(() => import("./features/perks/screens/main"));

const App = (props: any) => {
Expand Down
2 changes: 1 addition & 1 deletion src/common/components/entry-vote-btn/_index.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
@import "src/style/vars_mixins";
@import "../decks/columns/helpers/helpers";
@import "../../features/decks/columns/helpers/helpers";

.entry-vote-btn {
margin-right: 10px;
Expand Down
2 changes: 1 addition & 1 deletion src/common/components/navbar/sidebar/navbar-side.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import { History } from "history";
import { Button } from "@ui/button";
import { closeSvg } from "../../../img/svg";
import { NavbarPerksButton } from "../navbar-perks-button";
import { walletIconSvg } from "../../decks/icons";
import { useMappedStore } from "../../../store/use-mapped-store";
import { NavbarNotificationsButton } from "../navbar-notifications-button";
import { UilEditAlt } from "@iconscout/react-unicons";
import { classNameObject } from "../../../helper/class-name-object";
import { walletIconSvg } from "../../../features/decks/icons";

interface Props {
show: boolean;
Expand Down
2 changes: 1 addition & 1 deletion src/common/components/search-box/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { copyContent } from "../../img/svg";
import { success } from "../feedback";
import "./_index.scss";
import { FormControl, InputGroup } from "@ui/input";
import { searchIconSvg } from "../decks/icons";
import { Button } from "@ui/button";
import { searchIconSvg } from "../../features/decks/icons";

type Props = any;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import {
import { BlockedUsersModal } from "./blocked-users-modal";
import { useCommunityCache } from "../../../../core";
import { useMappedStore } from "../../../../store/use-mapped-store";
import { userIconSvg } from "../../../../components/decks/icons";
import { HiddenMessagesModal } from "./hidden-messages-modal";
import { userIconSvg } from "../../../decks/icons";

interface Props {
channel?: Channel;
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useMappedStore } from "../../../../store/use-mapped-store";
import React, { useContext, useState } from "react";
import { DeckGridContext } from "../../deck-manager";
import { UserAvatar } from "../../../user-avatar";
import { UserAvatar } from "../../../../components/user-avatar";
import { DeckAddColumnSearchBox } from "./deck-add-column-search-box";
import { SettingsProps, UsernameDataItem } from "./common";
import { COMMUNITY_CONTENT_TYPES, ICONS } from "../../consts";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useMappedStore } from "../../../../store/use-mapped-store";
import React, { useContext, useState } from "react";
import { DeckGridContext } from "../../deck-manager";
import { UserAvatar } from "../../../user-avatar";
import { UserAvatar } from "../../../../components/user-avatar";
import { DeckAddColumnSearchBox } from "./deck-add-column-search-box";
import { SettingsProps, UsernameDataItem } from "./common";
import { ICONS, NOTIFICATION_CONTENT_TYPES } from "../../consts";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React, { useEffect, useState } from "react";
import { lookupAccounts } from "../../../../api/hive";
import { error } from "../../../feedback";
import { error } from "../../../../components/feedback";
import { formatError } from "../../../../api/operations";
import { useMappedStore } from "../../../../store/use-mapped-store";
import useDebounce from "react-use/lib/useDebounce";
import { UserAvatar } from "../../../user-avatar";
import { UserAvatar } from "../../../../components/user-avatar";
import { getCommunities } from "../../../../api/bridge";
import { UsernameDataItem } from "./common";
import { closeSvg } from "../../../../img/svg";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { _t } from "../../../../i18n";
import { UserAvatar } from "../../../user-avatar";
import { UserAvatar } from "../../../../components/user-avatar";
import React, { useContext, useState } from "react";
import { useMappedStore } from "../../../../store/use-mapped-store";
import useLocalStorage from "react-use/lib/useLocalStorage";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useMappedStore } from "../../../../store/use-mapped-store";
import React, { useContext, useState } from "react";
import { DeckGridContext } from "../../deck-manager";
import { UserAvatar } from "../../../user-avatar";
import { UserAvatar } from "../../../../components/user-avatar";
import { DeckAddColumnSearchBox } from "./deck-add-column-search-box";
import { SettingsProps, UsernameDataItem } from "./common";
import { ICONS, USER_CONTENT_TYPES } from "../../consts";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useMappedStore } from "../../../../store/use-mapped-store";
import React, { useContext, useState } from "react";
import { DeckGridContext } from "../../deck-manager";
import { UserAvatar } from "../../../user-avatar";
import { UserAvatar } from "../../../../components/user-avatar";
import { DeckAddColumnSearchBox } from "./deck-add-column-search-box";
import { SettingsProps, UsernameDataItem } from "./common";
import { ICONS, WALLET_CONTENT_TYPES } from "../../consts";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Comment from "../../../comment";
import Comment from "../../../../components/comment";
import { useMappedStore } from "../../../../store/use-mapped-store";
import React, { useState } from "react";
import { _t } from "../../../../i18n";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ import "./_deck-post-viewer.scss";
import useMount from "react-use/lib/useMount";
import { arrowLeftSvg } from "../../../../img/svg";
import { renderPostBody } from "@ecency/render-helper";
import { EntryInfo } from "../../../entry-info";
import { EntryInfo } from "../../../../components/entry-info";
import { History } from "history";
import { Discussion } from "../../../discussion";
import { Discussion } from "../../../../components/discussion";
import { useMappedStore } from "../../../../store/use-mapped-store";
import { DeckPostViewerCommentBox } from "./deck-post-viewer-comment-box";
import { _t } from "../../../../i18n";
import { commentSvg, voteSvg } from "../../icons";
import EntryVoteBtn from "../../../entry-vote-btn";
import EntryVoteBtn from "../../../../components/entry-vote-btn";
import { EntriesCacheContext, useEntryCache } from "../../../../core";
import EntryVotes from "../../../entry-votes";
import EntryVotes from "../../../../components/entry-votes";
import { useResizeDetector } from "react-resize-detector";
import {
renderAuthors,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { arrowLeftSvg } from "../../../../img/svg";
import { Entry } from "../../../../store/entries/types";
import { getPostsRanked } from "../../../../api/bridge";
import { ListItemSkeleton, SearchListItem } from "../deck-items";
import { makePath } from "../../../entry-link";
import { makePath } from "../../../../components/entry-link";
import { Button } from "@ui/button";

interface Props {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import { useMappedStore } from "../../../../store/use-mapped-store";
import React, { Fragment, useContext, useEffect, useRef, useState } from "react";
import profileLink from "../../../profile-link";
import profileLink from "../../../../components/profile-link";
import { history } from "../../../../store";
import { dateToRelative } from "../../../../helper/parse-date";
import { Link } from "react-router-dom";
import { _t } from "../../../../i18n";
import Tooltip from "../../../tooltip";
import Tooltip from "../../../../components/tooltip";
import { pinSvg } from "../../../../img/svg";
import { catchPostImage, postBodySummary, proxifyImageSrc } from "@ecency/render-helper";
import EntryVoteBtn from "../../../entry-vote-btn";
import EntryPayout from "../../../entry-payout";
import EntryVotes from "../../../entry-votes";
import EntryReblogBtn from "../../../entry-reblog-btn";
import EntryMenu from "../../../entry-menu";
import EntryVoteBtn from "../../../../components/entry-vote-btn";
import EntryPayout from "../../../../components/entry-payout";
import EntryVotes from "../../../../components/entry-votes";
import EntryReblogBtn from "../../../../components/entry-reblog-btn";
import EntryMenu from "../../../../components/entry-menu";
import { transformMarkedContent } from "../../../../util/transform-marked-content";
import { EntryLink } from "../../../entry-link";
import { EntryLink } from "../../../../components/entry-link";
import { useInViewport } from "react-in-viewport";
import { commentSvg, voteSvg } from "../../icons";
import { EntriesCacheContext, useEntryCache } from "../../../../core";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React, { MutableRefObject } from "react";
import ReactDOM from "react-dom";
import { UserAvatar } from "../../../user-avatar";
import { UserAvatar } from "../../../../components/user-avatar";
import { Global } from "../../../../store/global/types";
import { DeckThreadLinkItem } from "./deck-thread-link-item";
import { getCGMarketApi } from "../../../market-swap-form/api/coingecko-api";
import { getCGMarketApi } from "../../../../components/market-swap-form/api/coingecko-api";
import { renderToString } from "react-dom/server";
import { _t } from "../../../../i18n";
import formattedNumber from "../../../../util/formatted-number";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createPortal } from "react-dom";
import React, { useEffect, useRef, useState } from "react";
import React, { useCallback, useEffect, useRef, useState } from "react";
import { useMappedStore } from "../../../../store/use-mapped-store";
import { renderPostBody } from "@ecency/render-helper";
import { IdentifiableEntry } from "../deck-threads-manager";
Expand All @@ -14,6 +14,7 @@ import {
renderTweets,
renderVideos
} from "./deck-thread-item-body-render-helper";
import { renderLiketu } from "../helpers";

interface Props {
entry: IdentifiableEntry;
Expand Down Expand Up @@ -50,7 +51,7 @@ export const DeckThreadItemBody = ({
if (!renderInitiated) {
renderBody();
}
}, [height]);
}, [height, entry]);

const renderBody = async () => {
setRenderInitiated(true);
Expand All @@ -59,6 +60,10 @@ export const DeckThreadItemBody = ({
renderAreaRef.current.innerHTML = await renderCurrencies(renderAreaRef?.current?.innerHTML);
}

if (entry.parent_author === "liketu.moments") {
return;
}

renderTags(renderAreaRef);
renderAuthors(renderAreaRef, global);
renderPostLinks(renderAreaRef);
Expand All @@ -71,12 +76,20 @@ export const DeckThreadItemBody = ({
renderTweets(renderAreaRef);
};

const renderContentBody = useCallback(() => {
if (entry.parent_author === "liketu.moments") {
return renderLiketu(entry);
}

return renderPostBody(entry, true, global.canUseWebp);
}, [entry, global.canUseWebp]);

return (
<div className="thread-item-body">
<div
ref={renderAreaRef}
className="thread-render"
dangerouslySetInnerHTML={{ __html: renderPostBody(entry, true, global.canUseWebp) }}
dangerouslySetInnerHTML={{ __html: renderContentBody() }}
/>
{currentViewingImage &&
createPortal(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { UserAvatar } from "../../../user-avatar";
import { UserAvatar } from "../../../../components/user-avatar";
import { Link } from "react-router-dom";
import { _t } from "../../../../i18n";
import { dateToRelative } from "../../../../helper/parse-date";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { useMappedStore } from "../../../../store/use-mapped-store";
import { useResizeDetector } from "react-resize-detector";
import React, { useContext, useEffect, useState } from "react";
import { UserAvatar } from "../../../user-avatar";
import EntryVoteBtn from "../../../entry-vote-btn";
import { UserAvatar } from "../../../../components/user-avatar";
import EntryVoteBtn from "../../../../components/entry-vote-btn";
import { History } from "history";
import { _t } from "../../../../i18n";
import { IdentifiableEntry } from "../deck-threads-manager";
import { commentSvg, voteSvg } from "../../icons";
import EntryVotes from "../../../entry-votes";
import EntryVotes from "../../../../components/entry-votes";
import { DeckThreadItemBody } from "./deck-thread-item-body";
import { classNameObject } from "../../../../helper/class-name-object";
import { useInViewport } from "react-in-viewport";
Expand All @@ -16,7 +16,7 @@ import { useEntryChecking } from "../../utils";
import { Entry } from "../../../../store/entries/types";
import { DeckThreadItemHeader } from "./deck-thread-item-header";
import { dateToRelative } from "../../../../helper/parse-date";
import EntryMenu from "../../../entry-menu";
import EntryMenu from "../../../../components/entry-menu";
import { Button } from "@ui/button";

export interface ThreadItemProps {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from "react";
import { GenericDeckColumn } from "./generic-deck-column";
import { DraggableProvidedDragHandleProps } from "react-beautiful-dnd";
import { _t } from "../../../i18n";
import { SwapMode } from "../../market-swap-form/swap-mode";
import { SwapMode } from "../../../components/market-swap-form/swap-mode";

interface Props {
id: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { ShortListItemSkeleton } from "./deck-items";
import { GenericDeckWithDataColumn } from "./generic-deck-with-data-column";
import { UserDeckGridItem } from "../types";
import { DraggableProvidedDragHandleProps } from "react-beautiful-dnd";
import NotificationListItem from "../../notifications/notification-list-item";
import { ApiNotification, NotificationFilter } from "../../../store/notifications/types";
import { useMappedStore } from "../../../store/use-mapped-store";
import { History } from "history";
Expand All @@ -19,6 +18,7 @@ import { DeckContentTypeColumnSettings } from "./deck-column-settings/deck-conte
import { _t } from "../../../i18n";
import { InfiniteScrollLoader } from "./helpers";
import { newDataComingPaginatedCondition } from "../utils";
import NotificationListItem from "../../../components/notifications/notification-list-item";

interface Props {
id: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ const DeckThreadsColumnComponent = ({ id, settings, history, draggable }: Props)
data={data}
newDataComingCondition={(newData) => newDataComingPaginatedCondition(newData, prevData)}
isReloading={isReloading}
isVirtualScroll={false}
isVirtualScroll={["ecency.waves", "liketu.moments"].includes(settings.host)}
isExpanded={!!currentViewingEntry}
isFirstLoaded={isFirstLoaded}
onReload={() => fetchData()}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { History } from "history";
import { UserDeckGridItem } from "../types";
import "./_deck-wallet-balance-column.scss";
import { getCurrencyTokenRate } from "../../../api/private-api";
import FormattedCurrency from "../../formatted-currency";
import { useMappedStore } from "../../../store/use-mapped-store";
import { getAccount, getConversionRequests } from "../../../api/hive";
import parseAsset from "../../../helper/parse-asset";
Expand All @@ -16,10 +15,11 @@ import formattedNumber from "../../../util/formatted-number";
import { vestsToHp } from "../../../helper/vesting";
import { getHiveEngineTokenBalances, getMetrics } from "../../../api/hive-engine";
import { getSpkWallet } from "../../../api/spk-api";
import { getEstimatedBalance } from "../../wallet-spk/util";
import { DeckGridContext } from "../deck-manager";
import { usePointsQuery } from "../../../api/queries";
import { Spinner } from "@ui/spinner";
import { getEstimatedBalance } from "../../../components/wallet-spk/util";
import FormattedCurrency from "../../../components/formatted-currency";

interface Props {
id: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { UserDeckGridItem } from "../types";
import { DraggableProvidedDragHandleProps } from "react-beautiful-dnd";
import { GenericDeckWithDataColumn } from "./generic-deck-with-data-column";
import { fetchTransactions } from "../../../store/transactions/fetchTransactions";
import { TransactionRow } from "../../transactions";
import { Transaction } from "../../../store/transactions/types";
import { useMappedStore } from "../../../store/use-mapped-store";
import { History } from "history";
Expand All @@ -13,6 +12,7 @@ import usePrevious from "react-use/lib/usePrevious";
import { DeckContentTypeColumnSettings } from "./deck-column-settings/deck-content-type-column-settings";
import { WALLET_CONTENT_TYPES } from "../consts";
import { _t } from "../../../i18n";
import { TransactionRow } from "../../../components/transactions";

interface Props {
id: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export const GenericDeckWithDataColumn = ({
<AutoSizer>
{({ height, width }) => (
<List
overscanRowCount={16}
overscanRowCount={8}
height={height}
width={width}
rowCount={visibleData.length}
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from "./infinite-scroll-loader";
export * from "./render-liketu";
24 changes: 24 additions & 0 deletions src/common/features/decks/columns/helpers/render-liketu.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Entry } from "../../../../store/entries/types";
import { renderPostBody } from "@ecency/render-helper";

export function renderLiketu(entry: Entry) {
const postTree = document.createElement("div");
const shadow = postTree.attachShadow({ mode: "open" });

shadow.innerHTML = renderPostBody(entry, true, true);
console.log(shadow.innerHTML);
const images = Array.from(shadow.querySelectorAll("img"));
const content = Array.from(shadow.querySelectorAll("p"));
const text = content[content.length - 1].innerText;

shadow.innerHTML = `<div class="ecency-liketu-post">
<div class="images-slider overflow-x-auto flex gap-3">
${images.map(
(image) => `<img class="w-full max-h-[400px] block" src="${image.src}" alt=""/>`
)}
</div>
${text ? `<div class="liketu-text mt-4">${text}<d/iv>` : ""}
</div>`;

return shadow.innerHTML;
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { PREFIX } from "../../util/local-storage";
import { createDeck, deleteDeck, getDecks, updateDeck } from "./deck-api";
import { useMappedStore } from "../../store/use-mapped-store";
import usePrevious from "react-use/lib/usePrevious";
import { error } from "../feedback";
import { error } from "../../components/feedback";
import { _t } from "../../i18n";

interface Context {
Expand Down Expand Up @@ -69,7 +69,9 @@ export const DeckManager = ({ children }: Props) => {
const [layout, setLayout] = useState(decks.decks[0]);
const previousLayout = usePrevious(layout);

const [scrollHandler, setScrollHandler] = useState({ handle: (key: number) => {} });
const [scrollHandler, setScrollHandler] = useState({
handle: (key: number) => {}
});

useEffect(() => {
if (persistedActiveDeck && decks.decks.find((d) => d.key === persistedActiveDeck)) {
Expand Down
Loading

0 comments on commit 6ea7c50

Please sign in to comment.