Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Next #530

Merged
merged 17 commits into from
Feb 6, 2025
Merged

Next #530

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,32 @@
# [2.2.0-beta.25](https://github.com/WatchItDev/watchit-app/compare/v2.2.0-beta.24...v2.2.0-beta.25) (2025-02-06)


### Bug Fixes

* update metadata ([b361028](https://github.com/WatchItDev/watchit-app/commit/b361028b9566581f9b1565d5509dbde1a1babffc))

# [2.2.0-beta.24](https://github.com/WatchItDev/watchit-app/compare/v2.2.0-beta.23...v2.2.0-beta.24) (2025-02-06)


### Bug Fixes

* improve message on expired session ([0db6364](https://github.com/WatchItDev/watchit-app/commit/0db6364185fb16de4afbc2751d1e8f9e396e8ce9))

# [2.2.0-beta.23](https://github.com/WatchItDev/watchit-app/compare/v2.2.0-beta.22...v2.2.0-beta.23) (2025-02-06)


### Bug Fixes

* **finance:** correct MMC amount in transfer message ([e2f47b5](https://github.com/WatchItDev/watchit-app/commit/e2f47b539918c71260cea36bb2cd460380c2abce))
* fullfill padding on attestations ([1920718](https://github.com/WatchItDev/watchit-app/commit/19207189548057eb73843c1669ba06853520bea7))
* mispelling ([9109afa](https://github.com/WatchItDev/watchit-app/commit/9109afa9f24a72351f20d1a1789bac3f0edc1a82))
* **utils:** improve email regex to avoid partial matches ([df33aff](https://github.com/WatchItDev/watchit-app/commit/df33aff15b4729f7eca71a924b45d26909701ee9))


### Features

* add trimming utility and integrate in publication view ([7e37fbc](https://github.com/WatchItDev/watchit-app/commit/7e37fbc583d1327d81e392e4cffb8ae7083875e5))

# [2.2.0-beta.22](https://github.com/WatchItDev/watchit-app/compare/v2.2.0-beta.21...v2.2.0-beta.22) (2025-02-02)


Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "watchit",
"author": "Watchit",
"type": "module",
"version": "2.2.0-beta.22",
"version": "2.2.0-beta.25",
"description": "Open videos everywhere",
"email": "[email protected]",
"private": true,
Expand Down
2 changes: 1 addition & 1 deletion src/components/avatar/avatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ interface AvatarProfileProps {

const AvatarProfile: FC<AvatarProfileProps> = ({ src, alt, sx, ...other }) => {
//Check if src is a valid URL starting with http or https; if not, use the dicebear API to generate a random avatar
const imageSrc = src.startsWith('http') || src.startsWith('https') ? src : dicebear(src);
const imageSrc = src.startsWith('http') || src.startsWith('blob') || src.startsWith('https') ? src : dicebear(src);

// Default styles for the Avatar component
sx = {
Expand Down
6 changes: 3 additions & 3 deletions src/hooks/use-account-session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ import { setAuthLoading, setSession, setBalance } from '@redux/auth';
import { useSession, useLogout } from '@lens-protocol/react-web';

// NOTIFICATIONS IMPORTS
import { ERRORS } from '@notifications/errors';
import { notifyError } from '@notifications/internal-notifications';
import { notifyWarning } from '@notifications/internal-notifications';

// WEB3AUTH IMPORTS
import { useWeb3Auth } from '@src/hooks/use-web3-auth';
import { useWeb3Session } from '@src/hooks/use-web3-session';
import {WARNING} from "@notifications/warnings.ts";

// ----------------------------------------------------------------------

Expand Down Expand Up @@ -51,7 +51,7 @@ export const useAccountSession = (): UseAccountSessionHook => {
dispatch(setBalance({ balance: 0 }));
dispatch(setSession({ session: { ...data, authenticated: false } }));
dispatch(setAuthLoading({ isSessionLoading: false }));
if (!silent) notifyError(ERRORS.BUNDLER_UNAVAILABLE);
if (!silent) notifyWarning(WARNING.BUNDLER_UNAVAILABLE);
}, [web3Auth.status]);

// Automatic checks on mount + interval
Expand Down
3 changes: 2 additions & 1 deletion src/sections/publication/view/publication-details-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import LoadingButton from '@mui/lab/LoadingButton';
import { useDispatch, useSelector } from 'react-redux';
import { openLoginModal } from '@redux/auth';
import { appId, PublicationType, usePublications } from '@lens-protocol/react-web';
import {trimPublicationContentExtraText} from "@src/utils/text-transform.ts";
import { useIsPolicyAuthorized } from '@src/hooks/use-is-policy-authorized.ts';
import { GLOBAL_CONSTANTS } from '@src/config-global.ts';

Expand Down Expand Up @@ -277,7 +278,7 @@ export default function PublicationDetailsView({ id }: Props) {
opacity: 0.8,
}}
>
<Markdown children={data?.metadata?.content} />
<Markdown children={trimPublicationContentExtraText(data?.metadata?.content)} />
</Box>
{showButton && (
<Button variant="outlined" onClick={toggleDescription} sx={{ mt: 2 }}>
Expand Down
7 changes: 1 addition & 6 deletions src/sections/user/profile-header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import ProfileJoin from "@src/sections/user/profile-join.tsx";
import ProfileUserInfo from "@src/sections/user/profile-user-info.tsx";
import ProfileWrapper from './profile-wrapper';
import ProfileToolbar from "@src/sections/user/profile-toolbar.tsx";
import ProfileTransfer from "@src/sections/user/profile-transfer.tsx";

// ----------------------------------------------------------------------
export interface ProfileHeaderProps {
Expand Down Expand Up @@ -127,11 +126,7 @@ const ProfileHeader = ({
{profile?.id !== sessionData?.profile?.id && (
<FollowUnfollowButton profileId={profile?.id} />
)}
{
sessionData?.authenticated && profile?.id !== sessionData?.profile?.id && (
<ProfileTransfer profile={profile} />
)
}

</Stack>
</Stack>
</ProfileWrapper>
Expand Down
9 changes: 9 additions & 0 deletions src/sections/user/profile-toolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {FC} from "react";
import {Profile} from "@lens-protocol/api-bindings";
import {useTheme} from "@mui/material/styles";
import {useSelector} from "react-redux";
import ProfileTransfer from "@src/sections/user/profile-transfer.tsx";

interface ProfileToolbarProps {
profile: Profile;
Expand Down Expand Up @@ -60,6 +61,14 @@ const ProfileToolbar: FC<ProfileToolbarProps> = ({profile, profileImage}) => {
{sessionData?.profile && profile?.id === sessionData?.profile?.id && (
<ProfileUpdateButton />
)}

{
sessionData?.authenticated && profile?.id !== sessionData?.profile?.id && (
<ProfileTransfer profile={profile} />
)
}


</Stack>
</Stack>
)
Expand Down
73 changes: 58 additions & 15 deletions src/sections/user/profile-transfer.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,51 @@
import {Profile} from "@lens-protocol/api-bindings";
import {FC} from "react";
import FinanceQuickTransferModal from "@src/sections/finance/components/finance-quick-transfer-modal.tsx";
import LoadingButton from "@mui/lab/LoadingButton";
import {useBoolean} from "@src/hooks/use-boolean.ts";
import { Profile } from '@lens-protocol/api-bindings';
import { FC, useCallback, useRef, useState } from 'react';
import FinanceQuickTransferModal from '@src/sections/finance/components/finance-quick-transfer-modal.tsx';
import LoadingButton from '@mui/lab/LoadingButton';
import { useBoolean } from '@src/hooks/use-boolean.ts';
import Iconify from '@src/components/iconify';
import Typography from '@mui/material/Typography';
import Popover from '@mui/material/Popover';

interface ProfileTransferProps {
profile: Profile;
}

const ProfileTransfer: FC<ProfileTransferProps> = ({profile}) => {
const ProfileTransfer: FC<ProfileTransferProps> = ({ profile }) => {
const [openTooltipSend, setOpenTooltipSend] = useState(false);
const navRefSend = useRef(null);
const confirm = useBoolean();

const handleOpen = () => {
confirm.onTrue();
}
};

const handleTransferFinish = () => {
confirm.onFalse();
}
};

const handleOpenSend = useCallback(() => {
setOpenTooltipSend(true);
}, []);

const handleCloseSend = useCallback(() => {
setOpenTooltipSend(false);
}, []);

return (
<>
<LoadingButton sx={{
minWidth: { xs: 90, md: 120 },
backgroundColor: '#24262A',
}} variant={'outlined'} onClick={handleOpen}>
Send
<LoadingButton
sx={{
backgroundColor: 'transparent',
minWidth: '44px',
}}
ref={navRefSend}
variant={'outlined'}
onClick={handleOpen}
onMouseEnter={handleOpenSend}
onMouseLeave={handleCloseSend}
>
<Iconify icon="streamline:arrow-transfer-diagonal-3" color="#fff" />
</LoadingButton>

<FinanceQuickTransferModal
Expand All @@ -37,8 +57,31 @@ const ProfileTransfer: FC<ProfileTransferProps> = ({profile}) => {
onFinish={handleTransferFinish}
contactInfo={profile}
/>

<Popover
open={openTooltipSend}
anchorEl={navRefSend.current}
anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}
transformOrigin={{ vertical: 'bottom', horizontal: 'center' }}
slotProps={{
paper: {
onMouseEnter: handleOpenSend,
onMouseLeave: handleCloseSend,
sx: {
mt: 6,
backgroundColor: 'rgba(0,0,0,0.6)',
padding: '8px 20px',
},
},
}}
sx={{
pointerEvents: 'none',
}}
>
<Typography>Send</Typography>
</Popover>
</>
)
}
);
};

export default ProfileTransfer;
2 changes: 0 additions & 2 deletions src/utils/notifications/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
*/
export enum ERRORS {
NOT_LOGGED_IN = 'NOT_LOGGED_IN',
BUNDLER_UNAVAILABLE = 'BUNDLER_UNAVAILABLE',
UNKNOWN_ERROR = 'UNKNOWN_ERROR',
METAMASK_CONNECTING_ERROR = 'METAMASK_CONNECTING_ERROR',
WITHDRAW_FAILED_ERROR = 'WITHDRAW_FAILED_ERROR',
Expand Down Expand Up @@ -98,7 +97,6 @@ export const ERROR_MESSAGES: Record<ERRORS, string> = {

// Withdraw error
[ERRORS.FIRST_LOGIN_ERROR]: 'You must login first to withdraw funds.',
[ERRORS.BUNDLER_UNAVAILABLE]: 'Your session is expired. Please re-login to continue.',

// Deposit error
[ERRORS.DEPOSIT_FAILED_ERROR]: 'Please login to deposit funds.',
Expand Down
2 changes: 2 additions & 0 deletions src/utils/notifications/warnings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export enum WARNING {
INVALID_DEPOSIT_AMOUNT = 'INVALID_DEPOSIT_AMOUNT',
INVALID_WITHDRAW_AMOUNT = 'INVALID_WITHDRAW_AMOUNT',
INVALID_WALLET_ADDRESS = 'INVALID_WALLET_ADDRESS',
BUNDLER_UNAVAILABLE = 'BUNDLER_UNAVAILABLE',
}

/**
Expand All @@ -18,4 +19,5 @@ export const WARNING_MESSAGES: Record<WARNING, string> = {
[WARNING.INVALID_DEPOSIT_AMOUNT]: 'Invalid deposit amount.',
[WARNING.INVALID_WITHDRAW_AMOUNT]: 'Invalid withdraw amount.',
[WARNING.INVALID_WALLET_ADDRESS]: 'Invalid wallet address.',
[WARNING.BUNDLER_UNAVAILABLE]: 'Session expired. Please login again.',
};
108 changes: 108 additions & 0 deletions src/utils/text-transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,111 @@ export const pascalToUpperSnake = (str: string): string => {
.toUpperCase() // Converts everything to uppercase
.replace(/^_/, ''); // Removes the initial underscore if it exists
};


/**
* An array of strings containing various special character patterns and names.
* The strings in this array include names or identifiers preceded by
* special characters such as dashes, question marks, or periods.
* Some entries also contain only special characters or brace-like structures.
*/
const specialChars = [
'—Huggo',
'?—Nick Riganas',
'.—Rhino',
'—Eric Johnson',
'—Jwelch5742',
'—yusufpiskin',
'—Maths Jesperson',
'—Mark Logan',
'—Snow Leopard',
'—Claudio Carvalho, Rio de Janeiro, Brazil',
'—Johnny-the-Film-Sentinel-2187',
'—grantss',
'—Ed Stephan',
'—filmfactsman',
'—Col Needham',
'—Tony Fontana',
'—garykmcd',
'—',
'?—',
'.—',
'{}',
];


/**
* A regular expression pattern used for matching and validating email addresses.
*
* This pattern supports common email formats, where:
* - The local part can contain alphanumeric characters, dots, underscores,
* percent signs, plus signs, and hyphens.
* - The domain part is structured as one or more labels separated by dots,
* with each label containing alphanumeric characters or hyphens.
* - The top-level domain must be at least two characters long and consist
* only of alphabetic characters.
*
* Flags:
* - The "g" flag enables global matching, allowing multiple occurrences
* of email addresses to be matched in a single string.
*/
const emailRegex = /\b[a-zA-Z0-9][a-zA-Z0-9._%+-]*@(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}\b/g;


/**
* Removes special characters from the given text string and returns the cleaned string.
*
* @param {string} text - The input string from which special characters will be removed.
* @return {string} - The resulting string after special characters are removed.
*/
function removeSpecialChars(text: string): string {
// Loop through the special characters and replace them with spaces
for (const char of specialChars) {
text = text.replace(char, '').trim();
}
return text;
}

/**
* Detects whether the given text contains a valid email address pattern.
*
* @param {string} text - The string to be checked for an email address.
* @return {boolean} Returns `true` if the text contains a valid email address, otherwise `false`.
*/
function detectEmail(text: string): boolean {
return emailRegex.test(text);
}

/**
* Removes an email address from the provided text string, if present.
*
* @param {string} text - The input string potentially containing an email address.
* @return {string} The modified string with the email address removed and trimmed of extra spaces.
*/
function removeEmail(text: string): string {
return text.replace(emailRegex, '').trim();
}

/**
* Processes and trims extra content from a publication text, including special characters,
* email addresses, and patterns at the end of the text.
*
* @param {string} text - The input string representing the publication content to be processed.
* @returns {string} The processed and cleaned text after applying trimming rules.
*/
export const trimPublicationContentExtraText = (text: string): string => {
const hasEmail = detectEmail(text);

if (hasEmail) {
text = removeEmail(text);
}

let cleanedText = removeSpecialChars(text);

// Verify if the last character is a period, if not, add one
if (!cleanedText.endsWith('.')) {
cleanedText += '.';
}

return `${cleanedText}`;
};