mirror of
https://github.com/Qortal/Qortal-Hub.git
synced 2025-07-23 04:36:52 +00:00
Refactor sReturn icon and set theme styles
This commit is contained in:
@@ -1,4 +1,11 @@
|
||||
import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
|
||||
import React, {
|
||||
useCallback,
|
||||
useContext,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react';
|
||||
import {
|
||||
AppCircle,
|
||||
AppCircleContainer,
|
||||
@@ -16,84 +23,95 @@ import {
|
||||
PublishQAppCTAParent,
|
||||
PublishQAppCTARight,
|
||||
PublishQAppDotsBG,
|
||||
} from "./Apps-styles";
|
||||
import { Avatar, Box, ButtonBase, InputBase, styled } from "@mui/material";
|
||||
import { Add } from "@mui/icons-material";
|
||||
import { MyContext, getBaseApiReact } from "../../App";
|
||||
import LogoSelected from "../../assets/svgs/LogoSelected.svg";
|
||||
import IconSearch from "../../assets/svgs/Search.svg";
|
||||
import IconClearInput from "../../assets/svgs/ClearInput.svg";
|
||||
import qappDevelopText from "../../assets/svgs/qappDevelopText.svg";
|
||||
import qappDots from "../../assets/svgs/qappDots.svg";
|
||||
import ReturnSVG from '../../assets/svgs/Return.svg'
|
||||
} from './Apps-styles';
|
||||
import { Avatar, Box, ButtonBase, InputBase, styled } from '@mui/material';
|
||||
import { Add } from '@mui/icons-material';
|
||||
import { MyContext, getBaseApiReact } from '../../App';
|
||||
import LogoSelected from '../../assets/svgs/LogoSelected.svg';
|
||||
import IconSearch from '../../assets/svgs/Search.svg';
|
||||
import IconClearInput from '../../assets/svgs/ClearInput.svg';
|
||||
import qappDevelopText from '../../assets/svgs/qappDevelopText.svg';
|
||||
import qappDots from '../../assets/svgs/qappDots.svg';
|
||||
import ReturnSVG from '../../assets/svgs/Return.svg';
|
||||
|
||||
import { Spacer } from "../../common/Spacer";
|
||||
import { AppInfoSnippet } from "./AppInfoSnippet";
|
||||
import { Virtuoso } from "react-virtuoso";
|
||||
import { executeEvent } from "../../utils/events";
|
||||
import { ComposeP, MailIconImg, ShowMessageReturnButton } from "../Group/Forum/Mail-styles";
|
||||
import { Spacer } from '../../common/Spacer';
|
||||
import { AppInfoSnippet } from './AppInfoSnippet';
|
||||
import { Virtuoso } from 'react-virtuoso';
|
||||
import { executeEvent } from '../../utils/events';
|
||||
import {
|
||||
ComposeP,
|
||||
MailIconImg,
|
||||
ShowMessageReturnButton,
|
||||
} from '../Group/Forum/Mail-styles';
|
||||
const officialAppList = [
|
||||
"q-tube",
|
||||
"q-blog",
|
||||
"q-share",
|
||||
"q-support",
|
||||
"q-mail",
|
||||
"q-fund",
|
||||
"q-shop",
|
||||
"q-trade",
|
||||
"q-support",
|
||||
"q-manager",
|
||||
"q-wallets",
|
||||
"q-search"
|
||||
'q-tube',
|
||||
'q-blog',
|
||||
'q-share',
|
||||
'q-support',
|
||||
'q-mail',
|
||||
'q-fund',
|
||||
'q-shop',
|
||||
'q-trade',
|
||||
'q-support',
|
||||
'q-manager',
|
||||
'q-wallets',
|
||||
'q-search',
|
||||
];
|
||||
|
||||
const ScrollerStyled = styled('div')({
|
||||
// Hide scrollbar for WebKit browsers (Chrome, Safari)
|
||||
"::-webkit-scrollbar": {
|
||||
width: "0px",
|
||||
height: "0px",
|
||||
},
|
||||
|
||||
// Hide scrollbar for Firefox
|
||||
scrollbarWidth: "none",
|
||||
|
||||
// Hide scrollbar for IE and older Edge
|
||||
"-msOverflowStyle": "none",
|
||||
});
|
||||
|
||||
const StyledVirtuosoContainer = styled('div')({
|
||||
position: 'relative',
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
|
||||
// Hide scrollbar for WebKit browsers (Chrome, Safari)
|
||||
"::-webkit-scrollbar": {
|
||||
width: "0px",
|
||||
height: "0px",
|
||||
},
|
||||
|
||||
// Hide scrollbar for Firefox
|
||||
scrollbarWidth: "none",
|
||||
|
||||
// Hide scrollbar for IE and older Edge
|
||||
"-msOverflowStyle": "none",
|
||||
});
|
||||
// Hide scrollbar for WebKit browsers (Chrome, Safari)
|
||||
'::-webkit-scrollbar': {
|
||||
width: '0px',
|
||||
height: '0px',
|
||||
},
|
||||
|
||||
export const AppsLibrary = ({ availableQapps, setMode, myName, hasPublishApp, isShow, categories={categories} }) => {
|
||||
const [searchValue, setSearchValue] = useState("");
|
||||
// Hide scrollbar for Firefox
|
||||
scrollbarWidth: 'none',
|
||||
|
||||
// Hide scrollbar for IE and older Edge
|
||||
'-msOverflowStyle': 'none',
|
||||
});
|
||||
|
||||
const StyledVirtuosoContainer = styled('div')({
|
||||
position: 'relative',
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
|
||||
// Hide scrollbar for WebKit browsers (Chrome, Safari)
|
||||
'::-webkit-scrollbar': {
|
||||
width: '0px',
|
||||
height: '0px',
|
||||
},
|
||||
|
||||
// Hide scrollbar for Firefox
|
||||
scrollbarWidth: 'none',
|
||||
|
||||
// Hide scrollbar for IE and older Edge
|
||||
'-msOverflowStyle': 'none',
|
||||
});
|
||||
|
||||
export const AppsLibrary = ({
|
||||
availableQapps,
|
||||
setMode,
|
||||
myName,
|
||||
hasPublishApp,
|
||||
isShow,
|
||||
categories = { categories },
|
||||
}) => {
|
||||
const [searchValue, setSearchValue] = useState('');
|
||||
const virtuosoRef = useRef();
|
||||
const { rootHeight } = useContext(MyContext);
|
||||
|
||||
const officialApps = useMemo(() => {
|
||||
return availableQapps.filter(
|
||||
(app) =>
|
||||
app.service === "APP" &&
|
||||
app.service === 'APP' &&
|
||||
officialAppList.includes(app?.name?.toLowerCase())
|
||||
);
|
||||
}, [availableQapps]);
|
||||
|
||||
const [debouncedValue, setDebouncedValue] = useState(""); // Debounced value
|
||||
const [debouncedValue, setDebouncedValue] = useState(''); // Debounced value
|
||||
|
||||
// Debounce logic
|
||||
useEffect(() => {
|
||||
@@ -117,23 +135,28 @@ export const AppsLibrary = ({ availableQapps, setMode, myName, hasPublishApp, i
|
||||
}, [debouncedValue]);
|
||||
|
||||
const rowRenderer = (index) => {
|
||||
|
||||
let app = searchedList[index];
|
||||
return <AppInfoSnippet key={`${app?.service}-${app?.name}`} app={app} myName={myName} />;
|
||||
return (
|
||||
<AppInfoSnippet
|
||||
key={`${app?.service}-${app?.name}`}
|
||||
app={app}
|
||||
myName={myName}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<AppsLibraryContainer sx={{
|
||||
display: !isShow && 'none'
|
||||
}}>
|
||||
<AppsWidthLimiter>
|
||||
<AppsLibraryContainer
|
||||
sx={{
|
||||
display: !isShow && 'none',
|
||||
}}
|
||||
>
|
||||
<AppsWidthLimiter>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
width: "100%",
|
||||
justifyContent: "center",
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
>
|
||||
<AppsSearchContainer>
|
||||
@@ -145,8 +168,8 @@ export const AppsLibrary = ({ availableQapps, setMode, myName, hasPublishApp, i
|
||||
sx={{ ml: 1, flex: 1 }}
|
||||
placeholder="Search for apps"
|
||||
inputProps={{
|
||||
"aria-label": "Search for apps",
|
||||
fontSize: "16px",
|
||||
'aria-label': 'Search for apps',
|
||||
fontSize: '16px',
|
||||
fontWeight: 400,
|
||||
}}
|
||||
/>
|
||||
@@ -155,7 +178,7 @@ export const AppsLibrary = ({ availableQapps, setMode, myName, hasPublishApp, i
|
||||
{searchValue && (
|
||||
<ButtonBase
|
||||
onClick={() => {
|
||||
setSearchValue("");
|
||||
setSearchValue('');
|
||||
}}
|
||||
>
|
||||
<img src={IconClearInput} />
|
||||
@@ -164,23 +187,27 @@ export const AppsLibrary = ({ availableQapps, setMode, myName, hasPublishApp, i
|
||||
</AppsSearchRight>
|
||||
</AppsSearchContainer>
|
||||
</Box>
|
||||
</AppsWidthLimiter>
|
||||
<Spacer height="25px" />
|
||||
<ShowMessageReturnButton sx={{
|
||||
padding: '2px'
|
||||
}} onClick={() => {
|
||||
executeEvent("navigateBack", {});
|
||||
|
||||
}}>
|
||||
<MailIconImg src={ReturnSVG} />
|
||||
<ComposeP>Return to Apps Dashboard</ComposeP>
|
||||
</ShowMessageReturnButton>
|
||||
<Spacer height="25px" />
|
||||
{searchedList?.length > 0 ? (
|
||||
<AppsWidthLimiter>
|
||||
<StyledVirtuosoContainer sx={{
|
||||
height: rootHeight
|
||||
}}>
|
||||
</AppsWidthLimiter>
|
||||
<Spacer height="25px" />
|
||||
<ShowMessageReturnButton
|
||||
sx={{
|
||||
padding: '2px',
|
||||
}}
|
||||
onClick={() => {
|
||||
executeEvent('navigateBack', {});
|
||||
}}
|
||||
>
|
||||
<MailIconImg src={ReturnSVG} />
|
||||
<ComposeP>Return to Apps Dashboard</ComposeP>
|
||||
</ShowMessageReturnButton>
|
||||
<Spacer height="25px" />
|
||||
{searchedList?.length > 0 ? (
|
||||
<AppsWidthLimiter>
|
||||
<StyledVirtuosoContainer
|
||||
sx={{
|
||||
height: rootHeight,
|
||||
}}
|
||||
>
|
||||
<Virtuoso
|
||||
ref={virtuosoRef}
|
||||
data={searchedList}
|
||||
@@ -188,14 +215,14 @@ export const AppsLibrary = ({ availableQapps, setMode, myName, hasPublishApp, i
|
||||
atBottomThreshold={50}
|
||||
followOutput="smooth"
|
||||
components={{
|
||||
Scroller: ScrollerStyled // Use the styled scroller component
|
||||
Scroller: ScrollerStyled, // Use the styled scroller component
|
||||
}}
|
||||
/>
|
||||
</StyledVirtuosoContainer>
|
||||
</AppsWidthLimiter>
|
||||
) : (
|
||||
<>
|
||||
<AppsWidthLimiter>
|
||||
</AppsWidthLimiter>
|
||||
) : (
|
||||
<>
|
||||
<AppsWidthLimiter>
|
||||
<AppLibrarySubTitle>Official Apps</AppLibrarySubTitle>
|
||||
<Spacer height="18px" />
|
||||
<AppsContainer>
|
||||
@@ -203,14 +230,14 @@ export const AppsLibrary = ({ availableQapps, setMode, myName, hasPublishApp, i
|
||||
return (
|
||||
<ButtonBase
|
||||
sx={{
|
||||
height: "80px",
|
||||
width: "60px",
|
||||
height: '80px',
|
||||
width: '60px',
|
||||
}}
|
||||
onClick={()=> {
|
||||
onClick={() => {
|
||||
// executeEvent("addTab", {
|
||||
// data: qapp
|
||||
// })
|
||||
executeEvent("selectedAppInfo", {
|
||||
executeEvent('selectedAppInfo', {
|
||||
data: qapp,
|
||||
});
|
||||
}}
|
||||
@@ -218,13 +245,13 @@ export const AppsLibrary = ({ availableQapps, setMode, myName, hasPublishApp, i
|
||||
<AppCircleContainer>
|
||||
<AppCircle
|
||||
sx={{
|
||||
border: "none",
|
||||
border: 'none',
|
||||
}}
|
||||
>
|
||||
<Avatar
|
||||
sx={{
|
||||
height: "31px",
|
||||
width: "31px",
|
||||
height: '31px',
|
||||
width: '31px',
|
||||
}}
|
||||
alt={qapp?.name}
|
||||
src={`${getBaseApiReact()}/arbitrary/THUMBNAIL/${
|
||||
@@ -233,8 +260,8 @@ export const AppsLibrary = ({ availableQapps, setMode, myName, hasPublishApp, i
|
||||
>
|
||||
<img
|
||||
style={{
|
||||
width: "31px",
|
||||
height: "auto",
|
||||
width: '31px',
|
||||
height: 'auto',
|
||||
}}
|
||||
src={LogoSelected}
|
||||
alt="center-icon"
|
||||
@@ -250,77 +277,87 @@ export const AppsLibrary = ({ availableQapps, setMode, myName, hasPublishApp, i
|
||||
})}
|
||||
</AppsContainer>
|
||||
<Spacer height="30px" />
|
||||
<AppLibrarySubTitle>{hasPublishApp ? 'Update Apps!' : 'Create Apps!'}</AppLibrarySubTitle>
|
||||
<AppLibrarySubTitle>
|
||||
{hasPublishApp ? 'Update Apps!' : 'Create Apps!'}
|
||||
</AppLibrarySubTitle>
|
||||
<Spacer height="18px" />
|
||||
</AppsWidthLimiter>
|
||||
<PublishQAppCTAParent>
|
||||
<PublishQAppCTALeft>
|
||||
<PublishQAppDotsBG>
|
||||
|
||||
<img src={qappDots} />
|
||||
</AppsWidthLimiter>
|
||||
<PublishQAppCTAParent>
|
||||
<PublishQAppCTALeft>
|
||||
<PublishQAppDotsBG>
|
||||
<img src={qappDots} />
|
||||
</PublishQAppDotsBG>
|
||||
<Spacer width="29px" />
|
||||
<Spacer width="29px" />
|
||||
<img src={qappDevelopText} />
|
||||
</PublishQAppCTALeft>
|
||||
<PublishQAppCTARight onClick={()=> {
|
||||
setMode('publish')
|
||||
}}>
|
||||
<PublishQAppCTAButton>
|
||||
{hasPublishApp ? 'Update' : 'Publish'}
|
||||
</PublishQAppCTAButton>
|
||||
<Spacer width="20px" />
|
||||
</PublishQAppCTARight>
|
||||
</PublishQAppCTAParent>
|
||||
<AppsWidthLimiter>
|
||||
|
||||
</PublishQAppCTALeft>
|
||||
<PublishQAppCTARight
|
||||
onClick={() => {
|
||||
setMode('publish');
|
||||
}}
|
||||
>
|
||||
<PublishQAppCTAButton>
|
||||
{hasPublishApp ? 'Update' : 'Publish'}
|
||||
</PublishQAppCTAButton>
|
||||
<Spacer width="20px" />
|
||||
</PublishQAppCTARight>
|
||||
</PublishQAppCTAParent>
|
||||
<AppsWidthLimiter>
|
||||
<Spacer height="18px" />
|
||||
<AppLibrarySubTitle>Categories</AppLibrarySubTitle>
|
||||
<Spacer height="18px" />
|
||||
<AppsWidthLimiter sx={{
|
||||
flexDirection: 'row',
|
||||
overflowX: 'auto',
|
||||
width: '100%',
|
||||
gap: '5px',
|
||||
"::-webkit-scrollbar": {
|
||||
width: "0px",
|
||||
height: "0px",
|
||||
},
|
||||
|
||||
// Hide scrollbar for Firefox
|
||||
scrollbarWidth: "none",
|
||||
|
||||
// Hide scrollbar for IE and older Edge
|
||||
"-msOverflowStyle": "none",
|
||||
}}>
|
||||
{categories?.map((category)=> {
|
||||
return (
|
||||
<ButtonBase key={category?.id} onClick={()=> {
|
||||
executeEvent('selectedCategory', {
|
||||
data: category
|
||||
})
|
||||
}}>
|
||||
<Box sx={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
height: '110px',
|
||||
width: '110px',
|
||||
background: 'linear-gradient(163.47deg, #4BBCFE 27.55%, #1386C9 86.56%)',
|
||||
color: '#1D1D1E',
|
||||
fontWeight: 700,
|
||||
fontSize: '16px',
|
||||
flexShrink: 0,
|
||||
borderRadius: '11px'
|
||||
}}>
|
||||
{category?.name}
|
||||
</Box>
|
||||
</ButtonBase>
|
||||
)
|
||||
})}
|
||||
<AppsWidthLimiter
|
||||
sx={{
|
||||
flexDirection: 'row',
|
||||
overflowX: 'auto',
|
||||
width: '100%',
|
||||
gap: '5px',
|
||||
'::-webkit-scrollbar': {
|
||||
width: '0px',
|
||||
height: '0px',
|
||||
},
|
||||
|
||||
// Hide scrollbar for Firefox
|
||||
scrollbarWidth: 'none',
|
||||
|
||||
// Hide scrollbar for IE and older Edge
|
||||
'-msOverflowStyle': 'none',
|
||||
}}
|
||||
>
|
||||
{categories?.map((category) => {
|
||||
return (
|
||||
<ButtonBase
|
||||
key={category?.id}
|
||||
onClick={() => {
|
||||
executeEvent('selectedCategory', {
|
||||
data: category,
|
||||
});
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
height: '110px',
|
||||
width: '110px',
|
||||
background:
|
||||
'linear-gradient(163.47deg, #4BBCFE 27.55%, #1386C9 86.56%)',
|
||||
color: '#1D1D1E',
|
||||
fontWeight: 700,
|
||||
fontSize: '16px',
|
||||
flexShrink: 0,
|
||||
borderRadius: '11px',
|
||||
}}
|
||||
>
|
||||
{category?.name}
|
||||
</Box>
|
||||
</ButtonBase>
|
||||
);
|
||||
})}
|
||||
</AppsWidthLimiter>
|
||||
</AppsWidthLimiter>
|
||||
</>
|
||||
)}
|
||||
</AppsLibraryContainer>
|
||||
</AppsWidthLimiter>
|
||||
</>
|
||||
)}
|
||||
</AppsLibraryContainer>
|
||||
);
|
||||
};
|
||||
|
@@ -5,7 +5,7 @@ import React, {
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
} from 'react';
|
||||
import {
|
||||
AppCircle,
|
||||
AppCircleContainer,
|
||||
@@ -23,77 +23,87 @@ import {
|
||||
PublishQAppCTAParent,
|
||||
PublishQAppCTARight,
|
||||
PublishQAppDotsBG,
|
||||
} from "./Apps-styles";
|
||||
import { Avatar, Box, ButtonBase, InputBase, Typography, styled } from "@mui/material";
|
||||
import { Add } from "@mui/icons-material";
|
||||
import { MyContext, getBaseApiReact } from "../../App";
|
||||
import LogoSelected from "../../assets/svgs/LogoSelected.svg";
|
||||
import IconSearch from "../../assets/svgs/Search.svg";
|
||||
import IconClearInput from "../../assets/svgs/ClearInput.svg";
|
||||
import qappDevelopText from "../../assets/svgs/qappDevelopText.svg";
|
||||
import qappLibraryText from "../../assets/svgs/qappLibraryText.svg";
|
||||
import RefreshIcon from "@mui/icons-material/Refresh";
|
||||
} from './Apps-styles';
|
||||
import {
|
||||
Avatar,
|
||||
Box,
|
||||
ButtonBase,
|
||||
InputBase,
|
||||
Typography,
|
||||
styled,
|
||||
} from '@mui/material';
|
||||
import { Add } from '@mui/icons-material';
|
||||
import { MyContext, getBaseApiReact } from '../../App';
|
||||
import LogoSelected from '../../assets/svgs/LogoSelected.svg';
|
||||
import IconSearch from '../../assets/svgs/Search.svg';
|
||||
import IconClearInput from '../../assets/svgs/ClearInput.svg';
|
||||
import qappDevelopText from '../../assets/svgs/qappDevelopText.svg';
|
||||
import qappLibraryText from '../../assets/svgs/qappLibraryText.svg';
|
||||
import RefreshIcon from '@mui/icons-material/Refresh';
|
||||
|
||||
import qappDots from "../../assets/svgs/qappDots.svg";
|
||||
import qappDots from '../../assets/svgs/qappDots.svg';
|
||||
|
||||
import { Spacer } from "../../common/Spacer";
|
||||
import { AppInfoSnippet } from "./AppInfoSnippet";
|
||||
import { Virtuoso } from "react-virtuoso";
|
||||
import { executeEvent } from "../../utils/events";
|
||||
import { Spacer } from '../../common/Spacer';
|
||||
import { AppInfoSnippet } from './AppInfoSnippet';
|
||||
import { Virtuoso } from 'react-virtuoso';
|
||||
import { executeEvent } from '../../utils/events';
|
||||
import {
|
||||
AppsDesktopLibraryBody,
|
||||
AppsDesktopLibraryHeader,
|
||||
} from "./AppsDesktop-styles";
|
||||
import { AppsNavBarDesktop } from "./AppsNavBarDesktop";
|
||||
import ReturnSVG from '../../assets/svgs/Return.svg'
|
||||
import { ComposeP, MailIconImg, ShowMessageReturnButton } from "../Group/Forum/Mail-styles";
|
||||
} from './AppsDesktop-styles';
|
||||
import ReturnSVG from '../../assets/svgs/Return.svg';
|
||||
import {
|
||||
ComposeP,
|
||||
MailIconImg,
|
||||
ShowMessageReturnButton,
|
||||
} from '../Group/Forum/Mail-styles';
|
||||
const officialAppList = [
|
||||
"q-tube",
|
||||
"q-blog",
|
||||
"q-share",
|
||||
"q-support",
|
||||
"q-mail",
|
||||
"q-fund",
|
||||
"q-shop",
|
||||
"q-trade",
|
||||
"q-support",
|
||||
"q-manager",
|
||||
"q-mintership",
|
||||
"q-wallets",
|
||||
"q-search"
|
||||
'q-tube',
|
||||
'q-blog',
|
||||
'q-share',
|
||||
'q-support',
|
||||
'q-mail',
|
||||
'q-fund',
|
||||
'q-shop',
|
||||
'q-trade',
|
||||
'q-support',
|
||||
'q-manager',
|
||||
'q-mintership',
|
||||
'q-wallets',
|
||||
'q-search',
|
||||
];
|
||||
|
||||
const ScrollerStyled = styled("div")({
|
||||
const ScrollerStyled = styled('div')({
|
||||
// Hide scrollbar for WebKit browsers (Chrome, Safari)
|
||||
"::-webkit-scrollbar": {
|
||||
width: "0px",
|
||||
height: "0px",
|
||||
'::-webkit-scrollbar': {
|
||||
width: '0px',
|
||||
height: '0px',
|
||||
},
|
||||
|
||||
// Hide scrollbar for Firefox
|
||||
scrollbarWidth: "none",
|
||||
scrollbarWidth: 'none',
|
||||
|
||||
// Hide scrollbar for IE and older Edge
|
||||
"-msOverflowStyle": "none",
|
||||
'-msOverflowStyle': 'none',
|
||||
});
|
||||
|
||||
const StyledVirtuosoContainer = styled("div")({
|
||||
position: "relative",
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
const StyledVirtuosoContainer = styled('div')({
|
||||
position: 'relative',
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
|
||||
// Hide scrollbar for WebKit browsers (Chrome, Safari)
|
||||
"::-webkit-scrollbar": {
|
||||
width: "0px",
|
||||
height: "0px",
|
||||
'::-webkit-scrollbar': {
|
||||
width: '0px',
|
||||
height: '0px',
|
||||
},
|
||||
|
||||
// Hide scrollbar for Firefox
|
||||
scrollbarWidth: "none",
|
||||
scrollbarWidth: 'none',
|
||||
|
||||
// Hide scrollbar for IE and older Edge
|
||||
"-msOverflowStyle": "none",
|
||||
'-msOverflowStyle': 'none',
|
||||
});
|
||||
|
||||
export const AppsLibraryDesktop = ({
|
||||
@@ -103,20 +113,20 @@ export const AppsLibraryDesktop = ({
|
||||
hasPublishApp,
|
||||
isShow,
|
||||
categories,
|
||||
getQapps
|
||||
getQapps,
|
||||
}) => {
|
||||
const [searchValue, setSearchValue] = useState("");
|
||||
const [searchValue, setSearchValue] = useState('');
|
||||
const virtuosoRef = useRef();
|
||||
|
||||
const officialApps = useMemo(() => {
|
||||
return availableQapps.filter(
|
||||
(app) =>
|
||||
app.service === "APP" &&
|
||||
app.service === 'APP' &&
|
||||
officialAppList.includes(app?.name?.toLowerCase())
|
||||
);
|
||||
}, [availableQapps]);
|
||||
|
||||
const [debouncedValue, setDebouncedValue] = useState(""); // Debounced value
|
||||
const [debouncedValue, setDebouncedValue] = useState(''); // Debounced value
|
||||
|
||||
// Debounce logic
|
||||
useEffect(() => {
|
||||
@@ -125,7 +135,7 @@ export const AppsLibraryDesktop = ({
|
||||
}, 350);
|
||||
setTimeout(() => {
|
||||
virtuosoRef.current.scrollToIndex({
|
||||
index: 0
|
||||
index: 0,
|
||||
});
|
||||
}, 500);
|
||||
// Cleanup timeout if searchValue changes before the timeout completes
|
||||
@@ -138,8 +148,13 @@ export const AppsLibraryDesktop = ({
|
||||
|
||||
const searchedList = useMemo(() => {
|
||||
if (!debouncedValue) return [];
|
||||
return availableQapps.filter((app) =>
|
||||
app.name.toLowerCase().includes(debouncedValue.toLowerCase()) || (app?.metadata?.title && app?.metadata?.title?.toLowerCase().includes(debouncedValue.toLowerCase()))
|
||||
return availableQapps.filter(
|
||||
(app) =>
|
||||
app.name.toLowerCase().includes(debouncedValue.toLowerCase()) ||
|
||||
(app?.metadata?.title &&
|
||||
app?.metadata?.title
|
||||
?.toLowerCase()
|
||||
.includes(debouncedValue.toLowerCase()))
|
||||
);
|
||||
}, [debouncedValue]);
|
||||
|
||||
@@ -151,7 +166,7 @@ export const AppsLibraryDesktop = ({
|
||||
app={app}
|
||||
myName={myName}
|
||||
parentStyles={{
|
||||
padding: '0px 10px'
|
||||
padding: '0px 10px',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
@@ -160,111 +175,112 @@ export const AppsLibraryDesktop = ({
|
||||
return (
|
||||
<AppsLibraryContainer
|
||||
sx={{
|
||||
display: !isShow && "none",
|
||||
padding: "0px",
|
||||
height: "100vh",
|
||||
overflow: "hidden",
|
||||
paddingTop: '30px'
|
||||
display: !isShow && 'none',
|
||||
padding: '0px',
|
||||
height: '100vh',
|
||||
overflow: 'hidden',
|
||||
paddingTop: '30px',
|
||||
}}
|
||||
>
|
||||
|
||||
<AppsDesktopLibraryHeader
|
||||
sx={{
|
||||
maxWidth: "1500px",
|
||||
width: "90%",
|
||||
maxWidth: '1500px',
|
||||
width: '90%',
|
||||
}}
|
||||
>
|
||||
<AppsWidthLimiter>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
width: "100%",
|
||||
justifyContent: "space-between",
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
justifyContent: 'space-between',
|
||||
}}
|
||||
>
|
||||
<img src={qappLibraryText} />
|
||||
<Box sx={{
|
||||
display: 'flex',
|
||||
gap: '20px',
|
||||
alignItems: 'center'
|
||||
}}>
|
||||
<AppsSearchContainer
|
||||
<Box
|
||||
sx={{
|
||||
width: "412px",
|
||||
display: 'flex',
|
||||
gap: '20px',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<AppsSearchLeft>
|
||||
<img src={IconSearch} />
|
||||
<InputBase
|
||||
value={searchValue}
|
||||
onChange={(e) => setSearchValue(e.target.value)}
|
||||
sx={{ ml: 1, flex: 1 }}
|
||||
placeholder="Search for apps"
|
||||
inputProps={{
|
||||
"aria-label": "Search for apps",
|
||||
fontSize: "16px",
|
||||
fontWeight: 400,
|
||||
<AppsSearchContainer
|
||||
sx={{
|
||||
width: '412px',
|
||||
}}
|
||||
>
|
||||
<AppsSearchLeft>
|
||||
<img src={IconSearch} />
|
||||
<InputBase
|
||||
value={searchValue}
|
||||
onChange={(e) => setSearchValue(e.target.value)}
|
||||
sx={{ ml: 1, flex: 1 }}
|
||||
placeholder="Search for apps"
|
||||
inputProps={{
|
||||
'aria-label': 'Search for apps',
|
||||
fontSize: '16px',
|
||||
fontWeight: 400,
|
||||
}}
|
||||
/>
|
||||
</AppsSearchLeft>
|
||||
<AppsSearchRight>
|
||||
{searchValue && (
|
||||
<ButtonBase
|
||||
onClick={() => {
|
||||
setSearchValue('');
|
||||
}}
|
||||
>
|
||||
<img src={IconClearInput} />
|
||||
</ButtonBase>
|
||||
)}
|
||||
</AppsSearchRight>
|
||||
</AppsSearchContainer>
|
||||
<ButtonBase
|
||||
onClick={(e) => {
|
||||
getQapps();
|
||||
}}
|
||||
>
|
||||
<RefreshIcon
|
||||
sx={{
|
||||
color: 'rgba(250, 250, 250, 0.5)',
|
||||
width: '40px',
|
||||
height: 'auto',
|
||||
}}
|
||||
/>
|
||||
</AppsSearchLeft>
|
||||
<AppsSearchRight>
|
||||
{searchValue && (
|
||||
<ButtonBase
|
||||
onClick={() => {
|
||||
setSearchValue("");
|
||||
}}
|
||||
>
|
||||
<img src={IconClearInput} />
|
||||
</ButtonBase>
|
||||
)}
|
||||
</AppsSearchRight>
|
||||
</AppsSearchContainer>
|
||||
<ButtonBase
|
||||
onClick={(e) => {
|
||||
getQapps()
|
||||
}}
|
||||
>
|
||||
<RefreshIcon
|
||||
|
||||
sx={{
|
||||
color: "rgba(250, 250, 250, 0.5)",
|
||||
width: '40px',
|
||||
height: 'auto'
|
||||
}}
|
||||
/>
|
||||
</ButtonBase>
|
||||
</ButtonBase>
|
||||
</Box>
|
||||
|
||||
</Box>
|
||||
</AppsWidthLimiter>
|
||||
</AppsDesktopLibraryHeader>
|
||||
<AppsDesktopLibraryBody
|
||||
sx={{
|
||||
height: `calc(100vh - 36px)`,
|
||||
overflow: "auto",
|
||||
padding: "0px",
|
||||
alignItems: "center",
|
||||
overflow: 'auto',
|
||||
padding: '0px',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<AppsDesktopLibraryBody
|
||||
sx={{
|
||||
height: `calc(100vh - 36px)`,
|
||||
flexGrow: "unset",
|
||||
maxWidth: "1500px",
|
||||
width: "90%",
|
||||
flexGrow: 'unset',
|
||||
maxWidth: '1500px',
|
||||
width: '90%',
|
||||
}}
|
||||
>
|
||||
|
||||
<Spacer height="70px" />
|
||||
<ShowMessageReturnButton sx={{
|
||||
padding: '2px'
|
||||
}} onClick={() => {
|
||||
executeEvent("navigateBack", {});
|
||||
}}>
|
||||
<MailIconImg src={ReturnSVG} />
|
||||
<ComposeP>Return to Apps Dashboard</ComposeP>
|
||||
</ShowMessageReturnButton>
|
||||
<Spacer height="20px" />
|
||||
<ShowMessageReturnButton
|
||||
sx={{
|
||||
padding: '2px',
|
||||
}}
|
||||
onClick={() => {
|
||||
executeEvent('navigateBack', {});
|
||||
}}
|
||||
>
|
||||
<MailIconImg src={ReturnSVG} />
|
||||
<ComposeP>Return to Apps Dashboard</ComposeP>
|
||||
</ShowMessageReturnButton>
|
||||
<Spacer height="20px" />
|
||||
{searchedList?.length > 0 ? (
|
||||
<AppsWidthLimiter>
|
||||
<StyledVirtuosoContainer
|
||||
@@ -292,46 +308,48 @@ export const AppsLibraryDesktop = ({
|
||||
<>
|
||||
<AppLibrarySubTitle
|
||||
sx={{
|
||||
fontSize: "30px",
|
||||
fontSize: '30px',
|
||||
}}
|
||||
>
|
||||
Official Apps
|
||||
</AppLibrarySubTitle>
|
||||
<Spacer height="45px" />
|
||||
<AppsContainer sx={{
|
||||
gap: '50px',
|
||||
justifyContent: 'flex-start'
|
||||
}}>
|
||||
<AppsContainer
|
||||
sx={{
|
||||
gap: '50px',
|
||||
justifyContent: 'flex-start',
|
||||
}}
|
||||
>
|
||||
{officialApps?.map((qapp) => {
|
||||
return (
|
||||
<ButtonBase
|
||||
sx={{
|
||||
// height: "80px",
|
||||
width: "80px",
|
||||
width: '80px',
|
||||
}}
|
||||
onClick={() => {
|
||||
// executeEvent("addTab", {
|
||||
// data: qapp
|
||||
// })
|
||||
executeEvent("selectedAppInfo", {
|
||||
executeEvent('selectedAppInfo', {
|
||||
data: qapp,
|
||||
});
|
||||
}}
|
||||
>
|
||||
<AppCircleContainer
|
||||
sx={{
|
||||
gap: "10px",
|
||||
gap: '10px',
|
||||
}}
|
||||
>
|
||||
<AppCircle
|
||||
sx={{
|
||||
border: "none",
|
||||
border: 'none',
|
||||
}}
|
||||
>
|
||||
<Avatar
|
||||
sx={{
|
||||
height: "42px",
|
||||
width: "42px",
|
||||
height: '42px',
|
||||
width: '42px',
|
||||
}}
|
||||
alt={qapp?.name}
|
||||
src={`${getBaseApiReact()}/arbitrary/THUMBNAIL/${
|
||||
@@ -340,8 +358,8 @@ export const AppsLibraryDesktop = ({
|
||||
>
|
||||
<img
|
||||
style={{
|
||||
width: "31px",
|
||||
height: "auto",
|
||||
width: '31px',
|
||||
height: 'auto',
|
||||
}}
|
||||
src={LogoSelected}
|
||||
alt="center-icon"
|
||||
@@ -359,30 +377,30 @@ export const AppsLibraryDesktop = ({
|
||||
<Spacer height="80px" />
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
gap: "250px",
|
||||
display: "flex",
|
||||
width: '100%',
|
||||
gap: '250px',
|
||||
display: 'flex',
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
}}
|
||||
>
|
||||
<AppLibrarySubTitle
|
||||
sx={{
|
||||
fontSize: "30px",
|
||||
width: "100%",
|
||||
textAlign: "start",
|
||||
fontSize: '30px',
|
||||
width: '100%',
|
||||
textAlign: 'start',
|
||||
}}
|
||||
>
|
||||
{hasPublishApp ? "Update Apps!" : "Create Apps!"}
|
||||
{hasPublishApp ? 'Update Apps!' : 'Create Apps!'}
|
||||
</AppLibrarySubTitle>
|
||||
<Spacer height="18px" />
|
||||
<PublishQAppCTAParent
|
||||
sx={{
|
||||
gap: "25px",
|
||||
gap: '25px',
|
||||
}}
|
||||
>
|
||||
<PublishQAppCTALeft>
|
||||
@@ -394,11 +412,11 @@ export const AppsLibraryDesktop = ({
|
||||
</PublishQAppCTALeft>
|
||||
<PublishQAppCTARight
|
||||
onClick={() => {
|
||||
setMode("publish");
|
||||
setMode('publish');
|
||||
}}
|
||||
>
|
||||
<PublishQAppCTAButton>
|
||||
{hasPublishApp ? "Update" : "Publish"}
|
||||
{hasPublishApp ? 'Update' : 'Publish'}
|
||||
</PublishQAppCTAButton>
|
||||
<Spacer width="20px" />
|
||||
</PublishQAppCTARight>
|
||||
@@ -406,13 +424,13 @@ export const AppsLibraryDesktop = ({
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
}}
|
||||
>
|
||||
<AppLibrarySubTitle
|
||||
sx={{
|
||||
fontSize: "30px",
|
||||
fontSize: '30px',
|
||||
}}
|
||||
>
|
||||
Categories
|
||||
@@ -420,58 +438,57 @@ export const AppsLibraryDesktop = ({
|
||||
<Spacer height="18px" />
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
gap: "20px",
|
||||
flexWrap: "wrap",
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
gap: '20px',
|
||||
flexWrap: 'wrap',
|
||||
}}
|
||||
>
|
||||
<ButtonBase
|
||||
|
||||
onClick={() => {
|
||||
executeEvent("selectedCategory", {
|
||||
data: {
|
||||
id: 'all',
|
||||
name: 'All'
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
height: "60px",
|
||||
padding: "0px 24px",
|
||||
border: "4px solid #10242F",
|
||||
borderRadius: "6px",
|
||||
boxShadow: "2px 4px 0px 0px #000000",
|
||||
}}
|
||||
>
|
||||
All
|
||||
</Box>
|
||||
</ButtonBase>
|
||||
<ButtonBase
|
||||
onClick={() => {
|
||||
executeEvent('selectedCategory', {
|
||||
data: {
|
||||
id: 'all',
|
||||
name: 'All',
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
height: '60px',
|
||||
padding: '0px 24px',
|
||||
border: '4px solid #10242F',
|
||||
borderRadius: '6px',
|
||||
boxShadow: '2px 4px 0px 0px #000000',
|
||||
}}
|
||||
>
|
||||
All
|
||||
</Box>
|
||||
</ButtonBase>
|
||||
{categories?.map((category) => {
|
||||
return (
|
||||
<ButtonBase
|
||||
key={category?.id}
|
||||
onClick={() => {
|
||||
executeEvent("selectedCategory", {
|
||||
executeEvent('selectedCategory', {
|
||||
data: category,
|
||||
});
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
height: "60px",
|
||||
padding: "0px 24px",
|
||||
border: "4px solid #10242F",
|
||||
borderRadius: "6px",
|
||||
boxShadow: "2px 4px 0px 0px #000000",
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
height: '60px',
|
||||
padding: '0px 24px',
|
||||
border: '4px solid #10242F',
|
||||
borderRadius: '6px',
|
||||
boxShadow: '2px 4px 0px 0px #000000',
|
||||
}}
|
||||
>
|
||||
{category?.name}
|
||||
|
@@ -1,13 +1,13 @@
|
||||
import { ButtonBase, Typography, useTheme } from "@mui/material";
|
||||
import Box from "@mui/material/Box";
|
||||
import { HubsIcon } from "../../assets/Icons/HubsIcon";
|
||||
import { MessagingIcon } from "../../assets/Icons/MessagingIcon";
|
||||
import AppIcon from "../../assets/svgs/AppIcon.svg";
|
||||
import { ButtonBase, Typography, useTheme } from '@mui/material';
|
||||
import Box from '@mui/material/Box';
|
||||
import { HubsIcon } from '../../assets/Icons/HubsIcon';
|
||||
import { MessagingIcon } from '../../assets/Icons/MessagingIcon';
|
||||
import AppIcon from '../../assets/svgs/AppIcon.svg';
|
||||
|
||||
import { HomeIcon } from "../../assets/Icons/HomeIcon";
|
||||
import { Save } from "../Save/Save";
|
||||
import { useRecoilState } from "recoil";
|
||||
import { enabledDevModeAtom } from "../../atoms/global";
|
||||
import { HomeIcon } from '../../assets/Icons/HomeIcon';
|
||||
import { Save } from '../Save/Save';
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { enabledDevModeAtom } from '../../atoms/global';
|
||||
|
||||
export const IconWrapper = ({
|
||||
children,
|
||||
@@ -22,25 +22,25 @@ export const IconWrapper = ({
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
gap: "5px",
|
||||
flexDirection: "column",
|
||||
height: customWidth ? customWidth : disableWidth ? "auto" : "89px",
|
||||
width: customWidth ? customWidth : disableWidth ? "auto" : "89px",
|
||||
borderRadius: "50%",
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
gap: '5px',
|
||||
flexDirection: 'column',
|
||||
height: customWidth ? customWidth : disableWidth ? 'auto' : '89px',
|
||||
width: customWidth ? customWidth : disableWidth ? 'auto' : '89px',
|
||||
borderRadius: '50%',
|
||||
backgroundColor: selected
|
||||
? theme.palette.background.default
|
||||
: "transparent",
|
||||
: 'transparent',
|
||||
color: color ? color : theme.palette.text.primary,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
<Typography
|
||||
sx={{
|
||||
fontFamily: "Inter",
|
||||
fontSize: "12px",
|
||||
fontFamily: 'Inter',
|
||||
fontSize: '12px',
|
||||
fontWeight: 500,
|
||||
color: theme.palette.text.primary,
|
||||
}}
|
||||
@@ -72,20 +72,20 @@ export const DesktopFooter = ({
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
position: "absolute",
|
||||
width: '100%',
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
height: "100px", // Footer height
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
height: '100px', // Footer height
|
||||
zIndex: 1,
|
||||
justifyContent: "center",
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
gap: "20px",
|
||||
display: 'flex',
|
||||
gap: '20px',
|
||||
}}
|
||||
>
|
||||
<ButtonBase
|
||||
@@ -94,15 +94,13 @@ export const DesktopFooter = ({
|
||||
}}
|
||||
>
|
||||
<IconWrapper label="Home" selected={isHome}>
|
||||
<HomeIcon
|
||||
height={30}
|
||||
/>
|
||||
<HomeIcon height={30} />
|
||||
</IconWrapper>
|
||||
</ButtonBase>
|
||||
|
||||
<ButtonBase
|
||||
onClick={() => {
|
||||
setDesktopViewMode("apps");
|
||||
setDesktopViewMode('apps');
|
||||
setIsOpenSideViewDirects(false);
|
||||
setIsOpenSideViewGroups(false);
|
||||
}}
|
||||
@@ -114,7 +112,7 @@ export const DesktopFooter = ({
|
||||
|
||||
<ButtonBase
|
||||
onClick={() => {
|
||||
setDesktopSideView("groups");
|
||||
setDesktopSideView('groups');
|
||||
}}
|
||||
>
|
||||
<IconWrapper label="Groups" selected={isGroups}>
|
||||
@@ -122,10 +120,10 @@ export const DesktopFooter = ({
|
||||
height={30}
|
||||
color={
|
||||
hasUnreadGroups
|
||||
? "var(--danger)"
|
||||
? 'var(--danger)'
|
||||
: isGroups
|
||||
? "white"
|
||||
: "rgba(250, 250, 250, 0.5)"
|
||||
? 'white'
|
||||
: 'rgba(250, 250, 250, 0.5)'
|
||||
}
|
||||
/>
|
||||
</IconWrapper>
|
||||
@@ -133,7 +131,7 @@ export const DesktopFooter = ({
|
||||
|
||||
<ButtonBase
|
||||
onClick={() => {
|
||||
setDesktopSideView("directs");
|
||||
setDesktopSideView('directs');
|
||||
}}
|
||||
>
|
||||
<IconWrapper label="Messaging" selected={isDirects}>
|
||||
@@ -141,10 +139,10 @@ export const DesktopFooter = ({
|
||||
height={30}
|
||||
color={
|
||||
hasUnreadDirects
|
||||
? "var(--danger)"
|
||||
? 'var(--danger)'
|
||||
: isDirects
|
||||
? "white"
|
||||
: "rgba(250, 250, 250, 0.5)"
|
||||
? 'white'
|
||||
: 'rgba(250, 250, 250, 0.5)'
|
||||
}
|
||||
/>
|
||||
</IconWrapper>
|
||||
@@ -154,7 +152,7 @@ export const DesktopFooter = ({
|
||||
{isEnabledDevMode && (
|
||||
<ButtonBase
|
||||
onClick={() => {
|
||||
setDesktopViewMode("dev");
|
||||
setDesktopViewMode('dev');
|
||||
setIsOpenSideViewDirects(false);
|
||||
setIsOpenSideViewGroups(false);
|
||||
}}
|
||||
|
@@ -5,7 +5,7 @@ import React, {
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
} from 'react';
|
||||
import {
|
||||
Avatar,
|
||||
Box,
|
||||
@@ -14,8 +14,8 @@ import {
|
||||
IconButton,
|
||||
Skeleton,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
import { ShowMessage } from "./ShowMessageWithoutModal";
|
||||
} from '@mui/material';
|
||||
import { ShowMessage } from './ShowMessageWithoutModal';
|
||||
import {
|
||||
ComposeP,
|
||||
GroupContainer,
|
||||
@@ -28,34 +28,33 @@ import {
|
||||
ThreadInfoColumn,
|
||||
ThreadInfoColumnNameP,
|
||||
ThreadInfoColumnTime,
|
||||
} from "./Mail-styles";
|
||||
import { Spacer } from "../../../common/Spacer";
|
||||
import { threadIdentifier } from "./GroupMail";
|
||||
import LazyLoad from "../../../common/LazyLoad";
|
||||
import ReturnSVG from "../../../assets/svgs/Return.svg";
|
||||
import { NewThread } from "./NewThread";
|
||||
} from './Mail-styles';
|
||||
import { Spacer } from '../../../common/Spacer';
|
||||
import { threadIdentifier } from './GroupMail';
|
||||
import ReturnSVG from '../../../assets/svgs/Return.svg';
|
||||
import { NewThread } from './NewThread';
|
||||
import {
|
||||
decryptPublishes,
|
||||
getTempPublish,
|
||||
handleUnencryptedPublishes,
|
||||
} from "../../Chat/GroupAnnouncements";
|
||||
import { LoadingSnackbar } from "../../Snackbar/LoadingSnackbar";
|
||||
import { subscribeToEvent, unsubscribeFromEvent } from "../../../utils/events";
|
||||
import RefreshIcon from "@mui/icons-material/Refresh";
|
||||
} from '../../Chat/GroupAnnouncements';
|
||||
import { LoadingSnackbar } from '../../Snackbar/LoadingSnackbar';
|
||||
import { subscribeToEvent, unsubscribeFromEvent } from '../../../utils/events';
|
||||
import RefreshIcon from '@mui/icons-material/Refresh';
|
||||
import {
|
||||
getArbitraryEndpointReact,
|
||||
getBaseApiReact,
|
||||
isMobile,
|
||||
} from "../../../App";
|
||||
} from '../../../App';
|
||||
import {
|
||||
ArrowDownward as ArrowDownwardIcon,
|
||||
ArrowUpward as ArrowUpwardIcon,
|
||||
} from "@mui/icons-material";
|
||||
import { addDataPublishesFunc, getDataPublishesFunc } from "../Group";
|
||||
import { RequestQueueWithPromise } from "../../../utils/queue/queue";
|
||||
import { CustomLoader } from "../../../common/CustomLoader";
|
||||
import { WrapperUserAction } from "../../WrapperUserAction";
|
||||
import { formatTimestampForum } from "../../../utils/time";
|
||||
} from '@mui/icons-material';
|
||||
import { addDataPublishesFunc, getDataPublishesFunc } from '../Group';
|
||||
import { RequestQueueWithPromise } from '../../../utils/queue/queue';
|
||||
import { CustomLoader } from '../../../common/CustomLoader';
|
||||
import { WrapperUserAction } from '../../WrapperUserAction';
|
||||
import { formatTimestampForum } from '../../../utils/time';
|
||||
const requestQueueSaveToLocal = new RequestQueueWithPromise(1);
|
||||
const requestQueueDownloadPost = new RequestQueueWithPromise(3);
|
||||
interface ThreadProps {
|
||||
@@ -65,14 +64,10 @@ interface ThreadProps {
|
||||
members: any;
|
||||
}
|
||||
|
||||
const getEncryptedResource = async ({
|
||||
name,
|
||||
identifier,
|
||||
secretKey,
|
||||
resource,
|
||||
groupId,
|
||||
dataPublishes,
|
||||
}, isPrivate) => {
|
||||
const getEncryptedResource = async (
|
||||
{ name, identifier, secretKey, resource, groupId, dataPublishes },
|
||||
isPrivate
|
||||
) => {
|
||||
let data = dataPublishes[`${name}-${identifier}`];
|
||||
if (
|
||||
!data ||
|
||||
@@ -92,15 +87,18 @@ const getEncryptedResource = async ({
|
||||
};
|
||||
}
|
||||
data = await res.text();
|
||||
|
||||
if (data?.error || typeof data !== "string") return;
|
||||
|
||||
if (data?.error || typeof data !== 'string') return;
|
||||
await requestQueueSaveToLocal.enqueue(() => {
|
||||
return addDataPublishesFunc({ ...resource, data }, groupId, "thmsg");
|
||||
return addDataPublishesFunc({ ...resource, data }, groupId, 'thmsg');
|
||||
});
|
||||
} else {
|
||||
data = data.data;
|
||||
}
|
||||
const response = isPrivate === false ? handleUnencryptedPublishes([data]) : await decryptPublishes([{ data }], secretKey);
|
||||
const response =
|
||||
isPrivate === false
|
||||
? handleUnencryptedPublishes([data])
|
||||
: await decryptPublishes([{ data }], secretKey);
|
||||
|
||||
const messageData = response[0];
|
||||
return messageData.decryptedData;
|
||||
@@ -115,7 +113,7 @@ export const Thread = ({
|
||||
secretKey,
|
||||
getSecretKey,
|
||||
updateThreadActivityCurrentThread,
|
||||
isPrivate
|
||||
isPrivate,
|
||||
}: ThreadProps) => {
|
||||
const [tempPublishedList, setTempPublishedList] = useState([]);
|
||||
const [messages, setMessages] = useState<any[]>([]);
|
||||
@@ -129,7 +127,7 @@ export const Thread = ({
|
||||
|
||||
// Update: Use a new ref for the scrollable container
|
||||
const threadContainerRef = useRef(null);
|
||||
const threadBeginningRef = useRef(null)
|
||||
const threadBeginningRef = useRef(null);
|
||||
// New state variables
|
||||
const [showScrollButton, setShowScrollButton] = useState(false);
|
||||
const [isAtBottom, setIsAtBottom] = useState(false);
|
||||
@@ -140,7 +138,7 @@ export const Thread = ({
|
||||
const dataPublishes = useRef({});
|
||||
|
||||
const getSavedData = useCallback(async (groupId) => {
|
||||
const res = await getDataPublishesFunc(groupId, "thmsg");
|
||||
const res = await getDataPublishesFunc(groupId, 'thmsg');
|
||||
dataPublishes.current = res || {};
|
||||
}, []);
|
||||
|
||||
@@ -159,14 +157,17 @@ export const Thread = ({
|
||||
|
||||
const getIndividualMsg = async (message: any) => {
|
||||
try {
|
||||
const responseDataMessage = await getEncryptedResource({
|
||||
identifier: message.identifier,
|
||||
name: message.name,
|
||||
secretKey,
|
||||
resource: message,
|
||||
groupId: groupInfo?.groupId,
|
||||
dataPublishes: dataPublishes.current,
|
||||
}, isPrivate);
|
||||
const responseDataMessage = await getEncryptedResource(
|
||||
{
|
||||
identifier: message.identifier,
|
||||
name: message.name,
|
||||
secretKey,
|
||||
resource: message,
|
||||
groupId: groupInfo?.groupId,
|
||||
dataPublishes: dataPublishes.current,
|
||||
},
|
||||
isPrivate
|
||||
);
|
||||
|
||||
if (responseDataMessage?.error) {
|
||||
const fullObject = {
|
||||
@@ -201,7 +202,7 @@ export const Thread = ({
|
||||
try {
|
||||
let threadId = currentThread.threadId;
|
||||
|
||||
const keyTemp = "thread-post";
|
||||
const keyTemp = 'thread-post';
|
||||
const getTempAnnouncements = await getTempPublish();
|
||||
|
||||
if (getTempAnnouncements?.[keyTemp]) {
|
||||
@@ -232,10 +233,10 @@ export const Thread = ({
|
||||
const identifier = `thmsg-${threadId}`;
|
||||
let url = `${getBaseApiReact()}${getArbitraryEndpointReact()}?mode=ALL&service=${threadIdentifier}&identifier=${identifier}&limit=20&includemetadata=false&prefix=true`;
|
||||
if (!isReverse) {
|
||||
url = url + "&reverse=false";
|
||||
url = url + '&reverse=false';
|
||||
}
|
||||
if (isReverse) {
|
||||
url = url + "&reverse=true";
|
||||
url = url + '&reverse=true';
|
||||
}
|
||||
if (after) {
|
||||
url = url + `&after=${after}`;
|
||||
@@ -245,9 +246,9 @@ export const Thread = ({
|
||||
}
|
||||
|
||||
const response = await fetch(url, {
|
||||
method: "GET",
|
||||
method: 'GET',
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
const responseData = await response.json();
|
||||
@@ -263,14 +264,13 @@ export const Thread = ({
|
||||
setMessages(fullArrayMsg);
|
||||
if (before === null && after === null && isReverse) {
|
||||
setTimeout(() => {
|
||||
containerRef.current.scrollIntoView({ behavior: "smooth" });
|
||||
containerRef.current.scrollIntoView({ behavior: 'smooth' });
|
||||
}, 300);
|
||||
}
|
||||
if(after || before === null && after === null && !isReverse){
|
||||
if (after || (before === null && after === null && !isReverse)) {
|
||||
setTimeout(() => {
|
||||
threadBeginningRef.current.scrollIntoView();
|
||||
}, 100);
|
||||
|
||||
}
|
||||
|
||||
if (fullArrayMsg.length === 0) {
|
||||
@@ -282,9 +282,9 @@ export const Thread = ({
|
||||
fullArrayMsg[0].created
|
||||
}`;
|
||||
const responseNewer = await fetch(urlNewer, {
|
||||
method: "GET",
|
||||
method: 'GET',
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
const responseDataNewer = await responseNewer.json();
|
||||
@@ -300,9 +300,9 @@ export const Thread = ({
|
||||
fullArrayMsg[fullArrayMsg.length - 1].created
|
||||
}`;
|
||||
const responseOlder = await fetch(urlOlder, {
|
||||
method: "GET",
|
||||
method: 'GET',
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
const responseDataOlder = await responseOlder.json();
|
||||
@@ -316,7 +316,7 @@ export const Thread = ({
|
||||
updateThreadActivityCurrentThread();
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("error", error);
|
||||
console.log('error', error);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
getSavedData(groupId);
|
||||
@@ -325,9 +325,21 @@ export const Thread = ({
|
||||
[messages, secretKey]
|
||||
);
|
||||
const getMessages = React.useCallback(async () => {
|
||||
if (!currentThread || (!secretKey && isPrivate) || !groupInfo?.groupId || isPrivate === null) return;
|
||||
if (
|
||||
!currentThread ||
|
||||
(!secretKey && isPrivate) ||
|
||||
!groupInfo?.groupId ||
|
||||
isPrivate === null
|
||||
)
|
||||
return;
|
||||
await getMailMessages(currentThread, null, null, false, groupInfo?.groupId);
|
||||
}, [getMailMessages, currentThread, secretKey, groupInfo?.groupId, isPrivate]);
|
||||
}, [
|
||||
getMailMessages,
|
||||
currentThread,
|
||||
secretKey,
|
||||
groupInfo?.groupId,
|
||||
isPrivate,
|
||||
]);
|
||||
const firstMount = useRef(false);
|
||||
|
||||
const saveTimestamp = useCallback((currentThread: any, username?: string) => {
|
||||
@@ -339,7 +351,7 @@ export const Thread = ({
|
||||
return;
|
||||
const threadIdForLocalStorage = `qmail_threads_${currentThread?.threadData?.groupId}_${currentThread?.threadId}`;
|
||||
const threads = JSON.parse(
|
||||
localStorage.getItem(`qmail_threads_viewedtimestamp_${username}`) || "{}"
|
||||
localStorage.getItem(`qmail_threads_viewedtimestamp_${username}`) || '{}'
|
||||
);
|
||||
// Convert to an array of objects with identifier and all fields
|
||||
let dataArray = Object.entries(threads).map(([identifier, value]) => ({
|
||||
@@ -382,8 +394,8 @@ export const Thread = ({
|
||||
if (currentThreadRef.current?.threadId !== currentThread?.threadId) {
|
||||
firstMount.current = false;
|
||||
}
|
||||
if(!secretKey && isPrivate) return
|
||||
if (currentThread && !firstMount.current && isPrivate !== null) {
|
||||
if (!secretKey && isPrivate) return;
|
||||
if (currentThread && !firstMount.current && isPrivate !== null) {
|
||||
getMessagesMiddleware();
|
||||
}
|
||||
}, [currentThread, secretKey, isPrivate]);
|
||||
@@ -402,9 +414,9 @@ export const Thread = ({
|
||||
const identifier = `thmsg-${threadId}`;
|
||||
const url = `${getBaseApiReact()}${getArbitraryEndpointReact()}?mode=ALL&service=${threadIdentifier}&identifier=${identifier}&limit=20&includemetadata=false&offset=${0}&reverse=true&prefix=true`;
|
||||
const response = await fetch(url, {
|
||||
method: "GET",
|
||||
method: 'GET',
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
const responseData = await response.json();
|
||||
@@ -469,17 +481,17 @@ export const Thread = ({
|
||||
|
||||
const threadFetchModeFunc = (e) => {
|
||||
const mode = e.detail?.mode;
|
||||
if (mode === "last-page") {
|
||||
if (mode === 'last-page') {
|
||||
getMailMessages(currentThread, null, null, true, groupInfo?.groupId);
|
||||
}
|
||||
firstMount.current = true;
|
||||
};
|
||||
|
||||
React.useEffect(() => {
|
||||
subscribeToEvent("threadFetchMode", threadFetchModeFunc);
|
||||
subscribeToEvent('threadFetchMode', threadFetchModeFunc);
|
||||
|
||||
return () => {
|
||||
unsubscribeFromEvent("threadFetchMode", threadFetchModeFunc);
|
||||
unsubscribeFromEvent('threadFetchMode', threadFetchModeFunc);
|
||||
};
|
||||
}, []);
|
||||
|
||||
@@ -526,11 +538,11 @@ export const Thread = ({
|
||||
handleScroll();
|
||||
}, 400);
|
||||
|
||||
container.addEventListener("scroll", handleScroll);
|
||||
container.addEventListener('scroll', handleScroll);
|
||||
|
||||
// Cleanup
|
||||
return () => {
|
||||
container.removeEventListener("scroll", handleScroll);
|
||||
container.removeEventListener('scroll', handleScroll);
|
||||
};
|
||||
}, [messages]);
|
||||
|
||||
@@ -540,9 +552,9 @@ export const Thread = ({
|
||||
if (!container) return;
|
||||
|
||||
if (isAtBottom) {
|
||||
container.scrollTo({ top: 0, behavior: "smooth" }); // Scroll to top
|
||||
container.scrollTo({ top: 0, behavior: 'smooth' }); // Scroll to top
|
||||
} else {
|
||||
container.scrollTo({ top: container.scrollHeight, behavior: "smooth" }); // Scroll to bottom
|
||||
container.scrollTo({ top: container.scrollHeight, behavior: 'smooth' }); // Scroll to bottom
|
||||
}
|
||||
};
|
||||
|
||||
@@ -550,19 +562,19 @@ export const Thread = ({
|
||||
return (
|
||||
<GroupContainer
|
||||
sx={{
|
||||
position: "relative",
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
overflow: "hidden",
|
||||
position: 'relative',
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
// Removed the ref from here since the scrollable area has changed
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
flexShrink: 0, // Corrected property name
|
||||
}}
|
||||
>
|
||||
@@ -583,16 +595,16 @@ export const Thread = ({
|
||||
/>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
gap: isMobile ? "45px" : "35px",
|
||||
alignItems: "center",
|
||||
padding: isMobile && "5px",
|
||||
display: 'flex',
|
||||
gap: isMobile ? '45px' : '35px',
|
||||
alignItems: 'center',
|
||||
padding: isMobile && '5px',
|
||||
}}
|
||||
>
|
||||
<ShowMessageReturnButton
|
||||
sx={{
|
||||
padding: isMobile && "5px",
|
||||
minWidth: isMobile && "50px",
|
||||
padding: isMobile && '5px',
|
||||
minWidth: isMobile && '50px',
|
||||
}}
|
||||
onClick={() => {
|
||||
setMessages([]);
|
||||
@@ -608,9 +620,9 @@ export const Thread = ({
|
||||
<ButtonBase onClick={scrollToPosition}>
|
||||
<ArrowUpwardIcon
|
||||
sx={{
|
||||
color: "white",
|
||||
cursor: "pointer",
|
||||
fontSize: isMobile ? "28px" : "36px",
|
||||
color: 'white',
|
||||
cursor: 'pointer',
|
||||
fontSize: isMobile ? '28px' : '36px',
|
||||
}}
|
||||
/>
|
||||
</ButtonBase>
|
||||
@@ -618,9 +630,9 @@ export const Thread = ({
|
||||
<ButtonBase onClick={scrollToPosition}>
|
||||
<ArrowDownwardIcon
|
||||
sx={{
|
||||
color: "white",
|
||||
cursor: "pointer",
|
||||
fontSize: isMobile ? "28px" : "36px",
|
||||
color: 'white',
|
||||
cursor: 'pointer',
|
||||
fontSize: isMobile ? '28px' : '36px',
|
||||
}}
|
||||
/>
|
||||
</ButtonBase>
|
||||
@@ -631,45 +643,45 @@ export const Thread = ({
|
||||
<ThreadContainerFullWidth
|
||||
sx={{
|
||||
flexGrow: 1,
|
||||
overflow: "auto",
|
||||
overflow: 'auto',
|
||||
}}
|
||||
ref={threadContainerRef} // Updated ref attached here
|
||||
>
|
||||
<div ref={threadBeginningRef}/>
|
||||
<div ref={threadBeginningRef} />
|
||||
<ThreadContainer>
|
||||
<Spacer height={isMobile ? "10px" : "30px"} />
|
||||
<Spacer height={isMobile ? '10px' : '30px'} />
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
alignItems: "center",
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
width: '100%',
|
||||
alignItems: 'center',
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
}}
|
||||
>
|
||||
<GroupNameP
|
||||
sx={{
|
||||
fontSize: isMobile && "18px",
|
||||
fontSize: isMobile && '18px',
|
||||
}}
|
||||
>
|
||||
{currentThread?.threadData?.title}
|
||||
</GroupNameP>
|
||||
</Box>
|
||||
<Spacer height={"15px"} />
|
||||
<Spacer height={'15px'} />
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
alignItems: "center",
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
gap: "5px",
|
||||
width: '100%',
|
||||
alignItems: 'center',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
gap: '5px',
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
sx={{
|
||||
padding: isMobile && "5px",
|
||||
fontSize: isMobile && "14px",
|
||||
textTransformation: "capitalize",
|
||||
padding: isMobile && '5px',
|
||||
fontSize: isMobile && '14px',
|
||||
textTransformation: 'capitalize',
|
||||
}}
|
||||
onClick={() => {
|
||||
getMailMessages(
|
||||
@@ -687,9 +699,9 @@ export const Thread = ({
|
||||
</Button>
|
||||
<Button
|
||||
sx={{
|
||||
padding: isMobile && "5px",
|
||||
fontSize: isMobile && "14px",
|
||||
textTransformation: "capitalize",
|
||||
padding: isMobile && '5px',
|
||||
fontSize: isMobile && '14px',
|
||||
textTransformation: 'capitalize',
|
||||
}}
|
||||
onClick={() => {
|
||||
getMailMessages(
|
||||
@@ -707,9 +719,9 @@ export const Thread = ({
|
||||
</Button>
|
||||
<Button
|
||||
sx={{
|
||||
padding: isMobile && "5px",
|
||||
fontSize: isMobile && "14px",
|
||||
textTransformation: "capitalize",
|
||||
padding: isMobile && '5px',
|
||||
fontSize: isMobile && '14px',
|
||||
textTransformation: 'capitalize',
|
||||
}}
|
||||
onClick={() => {
|
||||
getMailMessages(
|
||||
@@ -727,9 +739,9 @@ export const Thread = ({
|
||||
</Button>
|
||||
<Button
|
||||
sx={{
|
||||
padding: isMobile && "5px",
|
||||
fontSize: isMobile && "14px",
|
||||
textTransformation: "capitalize",
|
||||
padding: isMobile && '5px',
|
||||
fontSize: isMobile && '14px',
|
||||
textTransformation: 'capitalize',
|
||||
}}
|
||||
onClick={() => {
|
||||
getMailMessages(
|
||||
@@ -746,35 +758,34 @@ export const Thread = ({
|
||||
Last
|
||||
</Button>
|
||||
</Box>
|
||||
<Spacer height={isMobile ? "10px" : "30px"} />
|
||||
<Spacer height={isMobile ? '10px' : '30px'} />
|
||||
{combinedListTempAndReal.map((message, index, list) => {
|
||||
let fullMessage = message;
|
||||
|
||||
if (hashMapMailMessages[message?.identifier]) {
|
||||
fullMessage = hashMapMailMessages[message.identifier];
|
||||
|
||||
|
||||
if (fullMessage?.error) {
|
||||
return (
|
||||
<SingleThreadParent
|
||||
sx={{
|
||||
height: "auto",
|
||||
height: 'auto',
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
style={{
|
||||
width: "100%",
|
||||
borderRadius: "8px",
|
||||
overflow: "hidden",
|
||||
position: "relative",
|
||||
flexDirection: "column",
|
||||
width: '100%',
|
||||
borderRadius: '8px',
|
||||
overflow: 'hidden',
|
||||
position: 'relative',
|
||||
flexDirection: 'column',
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
alignItems: "flex-start",
|
||||
gap: "10px",
|
||||
display: 'flex',
|
||||
alignItems: 'flex-start',
|
||||
gap: '10px',
|
||||
}}
|
||||
>
|
||||
<WrapperUserAction
|
||||
@@ -784,8 +795,8 @@ export const Thread = ({
|
||||
>
|
||||
<Avatar
|
||||
sx={{
|
||||
height: "50px",
|
||||
width: "50px",
|
||||
height: '50px',
|
||||
width: '50px',
|
||||
}}
|
||||
src={`${getBaseApiReact()}/arbitrary/THUMBNAIL/${
|
||||
message?.name
|
||||
@@ -812,23 +823,22 @@ export const Thread = ({
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
flexDirection: "column",
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
flexDirection: 'column',
|
||||
}}
|
||||
>
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: "18px",
|
||||
color: "white",
|
||||
fontSize: '18px',
|
||||
color: 'white',
|
||||
}}
|
||||
>
|
||||
{fullMessage?.error}
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
</Box>
|
||||
</SingleThreadParent>
|
||||
);
|
||||
@@ -855,23 +865,23 @@ export const Thread = ({
|
||||
return (
|
||||
<SingleThreadParent
|
||||
sx={{
|
||||
height: "auto",
|
||||
height: 'auto',
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
style={{
|
||||
width: "100%",
|
||||
borderRadius: "8px",
|
||||
overflow: "hidden",
|
||||
position: "relative",
|
||||
flexDirection: "column",
|
||||
width: '100%',
|
||||
borderRadius: '8px',
|
||||
overflow: 'hidden',
|
||||
position: 'relative',
|
||||
flexDirection: 'column',
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
alignItems: "flex-start",
|
||||
gap: "10px",
|
||||
display: 'flex',
|
||||
alignItems: 'flex-start',
|
||||
gap: '10px',
|
||||
}}
|
||||
>
|
||||
<WrapperUserAction
|
||||
@@ -881,8 +891,8 @@ export const Thread = ({
|
||||
>
|
||||
<Avatar
|
||||
sx={{
|
||||
height: "50px",
|
||||
width: "50px",
|
||||
height: '50px',
|
||||
width: '50px',
|
||||
}}
|
||||
src={`${getBaseApiReact()}/arbitrary/THUMBNAIL/${
|
||||
message?.name
|
||||
@@ -909,37 +919,36 @@ export const Thread = ({
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
flexDirection: "column",
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
flexDirection: 'column',
|
||||
}}
|
||||
>
|
||||
<CustomLoader />
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: "18px",
|
||||
color: "white",
|
||||
fontSize: '18px',
|
||||
color: 'white',
|
||||
}}
|
||||
>
|
||||
Downloading from QDN
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
</Box>
|
||||
</SingleThreadParent>
|
||||
);
|
||||
})}
|
||||
|
||||
|
||||
{!hasLastPage && !isLoading && (
|
||||
<>
|
||||
<Spacer height="20px" />
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
justifyContent: "flex-end",
|
||||
width: '100%',
|
||||
display: 'flex',
|
||||
justifyContent: 'flex-end',
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
@@ -955,7 +964,7 @@ export const Thread = ({
|
||||
);
|
||||
}}
|
||||
sx={{
|
||||
color: "white",
|
||||
color: 'white',
|
||||
}}
|
||||
>
|
||||
Refetch page
|
||||
@@ -964,112 +973,113 @@ export const Thread = ({
|
||||
</>
|
||||
)}
|
||||
|
||||
|
||||
<Box sx={{
|
||||
<Box
|
||||
sx={{
|
||||
width: '100%',
|
||||
visibility: messages?.length > 4 ? 'visible' : 'hidden'
|
||||
}}>
|
||||
<Spacer height="30px" />
|
||||
<Box
|
||||
visibility: messages?.length > 4 ? 'visible' : 'hidden',
|
||||
}}
|
||||
>
|
||||
<Spacer height="30px" />
|
||||
<Box
|
||||
sx={{
|
||||
width: '100%',
|
||||
alignItems: 'center',
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
gap: '5px',
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
sx={{
|
||||
width: "100%",
|
||||
alignItems: "center",
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
gap: "5px",
|
||||
padding: isMobile && '5px',
|
||||
fontSize: isMobile && '14px',
|
||||
textTransformation: 'capitalize',
|
||||
}}
|
||||
onClick={() => {
|
||||
getMailMessages(
|
||||
currentThread,
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
groupInfo?.groupId
|
||||
);
|
||||
}}
|
||||
disabled={!hasFirstPage}
|
||||
variant="contained"
|
||||
>
|
||||
<Button
|
||||
sx={{
|
||||
padding: isMobile && "5px",
|
||||
fontSize: isMobile && "14px",
|
||||
textTransformation: "capitalize",
|
||||
}}
|
||||
onClick={() => {
|
||||
getMailMessages(
|
||||
currentThread,
|
||||
null,
|
||||
null,
|
||||
false,
|
||||
groupInfo?.groupId
|
||||
);
|
||||
}}
|
||||
disabled={!hasFirstPage}
|
||||
variant="contained"
|
||||
>
|
||||
First
|
||||
</Button>
|
||||
<Button
|
||||
sx={{
|
||||
padding: isMobile && "5px",
|
||||
fontSize: isMobile && "14px",
|
||||
textTransformation: "capitalize",
|
||||
}}
|
||||
onClick={() => {
|
||||
getMailMessages(
|
||||
currentThread,
|
||||
messages[0].created,
|
||||
null,
|
||||
false,
|
||||
groupInfo?.groupId
|
||||
);
|
||||
}}
|
||||
disabled={!hasPreviousPage}
|
||||
variant="contained"
|
||||
>
|
||||
Previous
|
||||
</Button>
|
||||
<Button
|
||||
sx={{
|
||||
padding: isMobile && "5px",
|
||||
fontSize: isMobile && "14px",
|
||||
textTransformation: "capitalize",
|
||||
}}
|
||||
onClick={() => {
|
||||
getMailMessages(
|
||||
currentThread,
|
||||
null,
|
||||
messages[messages.length - 1].created,
|
||||
false,
|
||||
groupInfo?.groupId
|
||||
);
|
||||
}}
|
||||
disabled={!hasNextPage}
|
||||
variant="contained"
|
||||
>
|
||||
Next
|
||||
</Button>
|
||||
<Button
|
||||
sx={{
|
||||
padding: isMobile && "5px",
|
||||
fontSize: isMobile && "14px",
|
||||
textTransformation: "capitalize",
|
||||
}}
|
||||
onClick={() => {
|
||||
getMailMessages(
|
||||
currentThread,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
groupInfo?.groupId
|
||||
);
|
||||
}}
|
||||
disabled={!hasLastPage}
|
||||
variant="contained"
|
||||
>
|
||||
Last
|
||||
</Button>
|
||||
</Box>
|
||||
<Spacer height="30px" />
|
||||
First
|
||||
</Button>
|
||||
<Button
|
||||
sx={{
|
||||
padding: isMobile && '5px',
|
||||
fontSize: isMobile && '14px',
|
||||
textTransformation: 'capitalize',
|
||||
}}
|
||||
onClick={() => {
|
||||
getMailMessages(
|
||||
currentThread,
|
||||
messages[0].created,
|
||||
null,
|
||||
false,
|
||||
groupInfo?.groupId
|
||||
);
|
||||
}}
|
||||
disabled={!hasPreviousPage}
|
||||
variant="contained"
|
||||
>
|
||||
Previous
|
||||
</Button>
|
||||
<Button
|
||||
sx={{
|
||||
padding: isMobile && '5px',
|
||||
fontSize: isMobile && '14px',
|
||||
textTransformation: 'capitalize',
|
||||
}}
|
||||
onClick={() => {
|
||||
getMailMessages(
|
||||
currentThread,
|
||||
null,
|
||||
messages[messages.length - 1].created,
|
||||
false,
|
||||
groupInfo?.groupId
|
||||
);
|
||||
}}
|
||||
disabled={!hasNextPage}
|
||||
variant="contained"
|
||||
>
|
||||
Next
|
||||
</Button>
|
||||
<Button
|
||||
sx={{
|
||||
padding: isMobile && '5px',
|
||||
fontSize: isMobile && '14px',
|
||||
textTransformation: 'capitalize',
|
||||
}}
|
||||
onClick={() => {
|
||||
getMailMessages(
|
||||
currentThread,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
groupInfo?.groupId
|
||||
);
|
||||
}}
|
||||
disabled={!hasLastPage}
|
||||
variant="contained"
|
||||
>
|
||||
Last
|
||||
</Button>
|
||||
</Box>
|
||||
|
||||
<div ref={containerRef} />
|
||||
<Spacer height="30px" />
|
||||
</Box>
|
||||
|
||||
<div ref={containerRef} />
|
||||
</ThreadContainer>
|
||||
</ThreadContainerFullWidth>
|
||||
<LoadingSnackbar
|
||||
open={isLoading}
|
||||
info={{
|
||||
message: "Loading posts... please wait.",
|
||||
message: 'Loading posts... please wait.',
|
||||
}}
|
||||
/>
|
||||
</GroupContainer>
|
||||
|
@@ -4,56 +4,59 @@ import {
|
||||
TextField,
|
||||
TextFieldProps,
|
||||
styled,
|
||||
} from "@mui/material";
|
||||
import { forwardRef, useState } from "react";
|
||||
import VisibilityOffIcon from "@mui/icons-material/VisibilityOff";
|
||||
import VisibilityIcon from "@mui/icons-material/Visibility";
|
||||
useTheme,
|
||||
} from '@mui/material';
|
||||
import { forwardRef, useState } from 'react';
|
||||
import VisibilityOffIcon from '@mui/icons-material/VisibilityOff';
|
||||
import VisibilityIcon from '@mui/icons-material/Visibility';
|
||||
|
||||
export const CustomInput = styled(TextField)(({ theme }) => ({
|
||||
width: "183px",
|
||||
borderRadius: "5px",
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
outline: "none",
|
||||
input: {
|
||||
fontSize: 10,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: 400,
|
||||
color: theme.palette.text.primary,
|
||||
"&::placeholder": {
|
||||
fontSize: 16,
|
||||
color: theme.palette.text.disabled,
|
||||
},
|
||||
outline: "none",
|
||||
padding: "10px",
|
||||
width: '183px',
|
||||
borderRadius: '5px',
|
||||
backgroundColor: theme.palette.background.paper,
|
||||
outline: 'none',
|
||||
input: {
|
||||
fontSize: 10,
|
||||
fontFamily: 'Inter',
|
||||
fontWeight: 400,
|
||||
color: theme.palette.text.primary,
|
||||
'&::placeholder': {
|
||||
fontSize: 16,
|
||||
color: theme.palette.text.disabled,
|
||||
},
|
||||
"& .MuiOutlinedInput-root": {
|
||||
"& fieldset": {
|
||||
border: `0.5px solid ${theme.palette.divider}`,
|
||||
},
|
||||
"&:hover fieldset": {
|
||||
border: `0.5px solid ${theme.palette.divider}`,
|
||||
},
|
||||
"&.Mui-focused fieldset": {
|
||||
border: `0.5px solid ${theme.palette.divider}`,
|
||||
},
|
||||
outline: 'none',
|
||||
padding: '10px',
|
||||
},
|
||||
'& .MuiOutlinedInput-root': {
|
||||
'& fieldset': {
|
||||
border: `0.5px solid ${theme.palette.divider}`,
|
||||
},
|
||||
"& .MuiInput-underline:before": {
|
||||
borderBottom: "none",
|
||||
'&:hover fieldset': {
|
||||
border: `0.5px solid ${theme.palette.divider}`,
|
||||
},
|
||||
"& .MuiInput-underline:hover:not(.Mui-disabled):before": {
|
||||
borderBottom: "none",
|
||||
'&.Mui-focused fieldset': {
|
||||
border: `0.5px solid ${theme.palette.divider}`,
|
||||
},
|
||||
"& .MuiInput-underline:after": {
|
||||
borderBottom: "none",
|
||||
},
|
||||
}));
|
||||
},
|
||||
'& .MuiInput-underline:before': {
|
||||
borderBottom: 'none',
|
||||
},
|
||||
'& .MuiInput-underline:hover:not(.Mui-disabled):before': {
|
||||
borderBottom: 'none',
|
||||
},
|
||||
'& .MuiInput-underline:after': {
|
||||
borderBottom: 'none',
|
||||
},
|
||||
}));
|
||||
|
||||
export const PasswordField = forwardRef<HTMLInputElement, TextFieldProps>(
|
||||
({ ...props }, ref) => {
|
||||
const [canViewPassword, setCanViewPassword] = useState(false);
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<CustomInput
|
||||
type={canViewPassword ? "text" : "password"}
|
||||
type={canViewPassword ? 'text' : 'password'}
|
||||
InputProps={{
|
||||
endAdornment: (
|
||||
<InputAdornment
|
||||
@@ -70,7 +73,10 @@ export const PasswordField = forwardRef<HTMLInputElement, TextFieldProps>(
|
||||
>
|
||||
<VisibilityOffIcon
|
||||
sx={{
|
||||
color: "white",
|
||||
color:
|
||||
theme.palette.mode === 'dark'
|
||||
? 'rgba(255, 255, 255, 0.5)'
|
||||
: 'rgba(0, 0, 0, 0.3)',
|
||||
}}
|
||||
/>
|
||||
</ButtonBase>
|
||||
@@ -81,7 +87,10 @@ export const PasswordField = forwardRef<HTMLInputElement, TextFieldProps>(
|
||||
>
|
||||
<VisibilityIcon
|
||||
sx={{
|
||||
color: "white",
|
||||
color:
|
||||
theme.palette.mode === 'dark'
|
||||
? 'rgba(255, 255, 255, 0.5)'
|
||||
: 'rgba(0, 0, 0, 0.3)',
|
||||
}}
|
||||
/>
|
||||
</ButtonBase>
|
||||
|
Reference in New Issue
Block a user