Skip to content

Commit

Permalink
Merge pull request #111 from iuricmp/feat/mentions
Browse files Browse the repository at this point in the history
feat: Add mentions on text renderer
  • Loading branch information
iuricmp authored Jul 2, 2024
2 parents 6871a0c + f6f2932 commit 88e48fa
Show file tree
Hide file tree
Showing 9 changed files with 146 additions and 45 deletions.
49 changes: 30 additions & 19 deletions mobile/app/[account]/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { useEffect, useState } from "react";
import { useDispatch } from "react-redux";
import { router, useLocalSearchParams, useNavigation } from "expo-router";
import { Loading } from "@gno/components/loading";
import { AccountView } from "@gno/components/view";
import { useSearch } from "@gno/hooks/use-search";
import { Following, Post, User } from "@gno/types";
Expand All @@ -10,11 +9,15 @@ import { selectAccount } from "redux/features/accountSlice";
import { setFollows } from "redux/features/profileSlice";
import { useFeed } from "@gno/hooks/use-feed";
import { useUserCache } from "@gno/hooks/use-user-cache";
import ErrorView from "@gno/components/view/account/no-account-view";
import Layout from "@gno/components/layout";
import { colors } from "@gno/styles/colors";

export default function Page() {
const { accountName } = useLocalSearchParams<{ accountName: string }>();

const [loading, setLoading] = useState<string | undefined>(undefined);
const [error, setError] = useState<string | undefined>(undefined);
const [user, setUser] = useState<User | undefined>(undefined);
const [following, setFollowing] = useState<Following[]>([]);
const [followers, setFollowers] = useState<Following[]>([]);
Expand Down Expand Up @@ -43,13 +46,18 @@ export default function Page() {
const response = await search.getJsonUserByName(accountName);
setUser(response);

if (!response) {
setError(`The account '${accountName}' does not exist.`);
return;
}

const { followers } = await search.GetJsonFollowers(response.address);
setFollowers(followers);

const { following } = await search.GetJsonFollowing(response.address);
setFollowing(following);

const isUserFeed = response.address === currentUser.address
const isUserFeed = response.address === currentUser?.address;
if (isUserFeed) {
const total = await feed.fetchCount(response.address);
setTotalPosts(total);
Expand Down Expand Up @@ -114,23 +122,26 @@ export default function Page() {
router.navigate({ pathname: "/post/[post_id]", params: { post_id: item.id, address: item.user.address } });
};

if (!user || loading || !currentUser) {
return <Loading message="Profile Loading..." />;
}

return (
<AccountView
user={user}
totalPosts={totalPosts}
currentUser={currentUser}
following={following}
followers={followers}
onGnod={onGnod}
onPressPost={onPressPost}
onPressFollowing={onPressFollowing}
onPressFollowers={onPressFollowers}
onPressFollow={onPressFollow}
onPressUnfollow={onPressUnfollow}
/>
<Layout.Container>
<Layout.Header style={{ backgroundColor: colors.grayscale[200] }} />
{error || loading || !user || !currentUser ? (
<ErrorView message={error} />
) : (
<AccountView
user={user}
currentUser={currentUser}
totalPosts={totalPosts}
following={following}
followers={followers}
onGnod={onGnod}
onPressPost={onPressPost}
onPressFollowing={onPressFollowing}
onPressFollowers={onPressFollowers}
onPressFollow={onPressFollow}
onPressUnfollow={onPressUnfollow}
/>
)}
</Layout.Container>
);
}
4 changes: 2 additions & 2 deletions mobile/app/home/feed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ export default function Page() {
const [isLoading, setIsLoading] = useState(true);

const router = useRouter();
const feed = useFeed();
const navigation = useNavigation();
const feed = useFeed();
const ref = useRef<FlatList>(null);
const dispatch = useAppDispatch();

Expand Down Expand Up @@ -47,7 +47,7 @@ export default function Page() {
}, [navigation]);

const onPressPost = () => {
router.push("/post");
router.navigate({ pathname: "/post" });
};

const onPress = async (item: Post) => {
Expand Down
37 changes: 37 additions & 0 deletions mobile/components/feed/post-content-label.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { colors } from "@gno/styles/colors";
import React from "react";
import Autolink, { CustomMatcher } from "react-native-autolink";

const PATTERN = /@([a-z]+[_a-z0-9]{5,})/g;

type Props = {
onMentionPress?: (accountName: string) => void;
children: string;
};

const PostContentLabel: React.FC<Props> = ({ children, onMentionPress }) => {
return (
<Autolink
text={children}
email={false}
url={false}
matchers={[
{
pattern: PATTERN,
style: { color: colors.blue, fontWeight: "bold" },
getLinkText: (replacerArgs) => `@${replacerArgs[1]}`,
onPress: (match) => {
console.log("Pressed mention1 ", match);

const accountNameM1 = match.getReplacerArgs()[0];
const accountName = accountNameM1.replace("@", "");

onMentionPress ? onMentionPress(accountName) : null;
},
},
]}
/>
);
};

export default PostContentLabel;
9 changes: 5 additions & 4 deletions mobile/components/feed/post-row.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { useRouter } from "expo-router";
import RepostLabel from "./repost-label";
import { RepostRow } from "./repost-row";
import GnodLabel from "./gnod-label";
import PostContentLabel from "./post-content-label";

interface FeedProps {
post?: Post;
Expand All @@ -30,8 +31,8 @@ export function PostRow({ post, onPress = func, onGnod = func, showFooter = true
router.navigate({ pathname: "/repost" });
};

const onPressName = async () => {
router.navigate({ pathname: "account", params: { accountName: post?.user.name } });
const nativgateToAccount = async (accountName: string) => {
router.navigate({ pathname: "account", params: { accountName } });
};

if (!post) {
Expand All @@ -45,13 +46,13 @@ export function PostRow({ post, onPress = func, onGnod = func, showFooter = true
<Image source={{ uri: post.user.image }} style={styles.image} />
<View style={styles.content}>
<View style={{ flexDirection: "row", alignItems: "center" }}>
<Pressable style={{ flexDirection: "row", alignItems: "center" }} onPress={onPressName}>
<Pressable style={{ flexDirection: "row", alignItems: "center" }} onPress={() => nativgateToAccount(post?.user.name)}>
<Text.Body style={[{ fontWeight: "bold", fontSize: 16, paddingRight: 8 }]}>@{post.user.name}</Text.Body>
<TimeStampLabel timestamp={post.date} />
</Pressable>
</View>

<Text.Body selectable>{post.post}</Text.Body>
<PostContentLabel onMentionPress={(value) => nativgateToAccount(value)}>{post.post}</PostContentLabel>
{isRepost ? <RepostRow post={post.repost_parent} onPress={onPress} showFooter={false} /> : null}
</View>
</View>
Expand Down
30 changes: 17 additions & 13 deletions mobile/components/layout/header.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from "react";
import { StyleSheet, TouchableOpacity, View, Text } from "react-native";
import Icons from "../icons";
import { useNavigation } from "@react-navigation/native";
import { useRouter } from "expo-router";

type Props = {
iconType?: "close" | "back";
Expand All @@ -12,16 +12,20 @@ type Props = {
};

const Header: React.FC<Props> = ({ iconType = "close", onCloseHandler, title = "", subtitle = "", style }) => {
const navigate = useNavigation();
const router = useRouter();

if (!onCloseHandler) {
onCloseHandler = () => {
navigate.goBack();
if (router.canGoBack()) {
router.back();
} else {
router.navigate({ pathname: "/home" });
}
};
}

return (
<View style={styles.container}>
<View style={[styles.container, style]}>
<TouchableOpacity style={styles.closeButton} onPress={onCloseHandler}>
{iconType === "close" ? <Icons.Close /> : <Icons.ArrowLeft />}
</TouchableOpacity>
Expand All @@ -43,15 +47,15 @@ const styles = StyleSheet.create({
paddingLeft: 16,
},
contentArea: { flex: 1, alignItems: "center", paddingRight: 36 },
title: {
fontSize: 16,
fontWeight: "bold",
color: "#000000",
},
subtitle: {
fontSize: 12,
color: "#000000",
},
title: {
fontSize: 16,
fontWeight: "bold",
color: "#000000",
},
subtitle: {
fontSize: 12,
color: "#000000",
},
});

export default Header;
6 changes: 2 additions & 4 deletions mobile/components/view/account/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,7 @@ function AccountView(props: Props) {
const isFollowed = useMemo(() => followers.find((f) => f.address === currentUser.address) != null, [user, followers]);

return (
<Layout.Container>
<Layout.Header style={styles.headerButton} />
<>
<View style={styles.container}>
<View style={styles.banner}>
<Image source={{ uri: "https://www.gravatar.com/avatar/tmp" }} style={styles.avatar} />
Expand Down Expand Up @@ -84,12 +83,11 @@ function AccountView(props: Props) {
<FeedView totalPosts={totalPosts} onPress={onPressPost} onGnod={onGnod} address={user.address} type="userPosts" />
</View>
</View>
</Layout.Container>
</>
);
}

const styles = StyleSheet.create({
headerButton: { backgroundColor: colors.grayscale[200] },
avatar: {
width: 120,
height: 120,
Expand Down
28 changes: 28 additions & 0 deletions mobile/components/view/account/no-account-view.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import Layout from "@gno/components/layout";
import Text from "@gno/components/text";
import React from "react";
import styled from "styled-components/native";

type Props = {
message?: string;
};

export const ErrorView: React.FC<Props> = ({ message = "Loading" }) => {
return (
<Layout.Container>
<Layout.Body>
<ViewCenter>
<Text.BodyMedium>{message}</Text.BodyMedium>
</ViewCenter>
</Layout.Body>
</Layout.Container>
);
};

const ViewCenter = styled.View`
height: 100%;
justify-content: center;
align-items: center;
`;

export default ErrorView;
21 changes: 21 additions & 0 deletions mobile/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions mobile/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@
"base-64": "^1.0.0",
"date-fns": "^3.6.0",
"expo": "~51.0.8",
"expo-application": "~5.9.1",
"expo-clipboard": "~6.0.3",
"expo-constants": "~16.0.2",
"expo-device": "~6.0.2",
"expo-linear-gradient": "~13.0.2",
"expo-linking": "~6.3.1",
"expo-notifications": "~0.28.6",
"expo-router": "~3.5.14",
Expand All @@ -36,6 +38,7 @@
"react": "18.2.0",
"react-dom": "^18.2.0",
"react-native": "0.74.1",
"react-native-autolink": "^4.2.0",
"react-native-fetch-api": "^3.0.0",
"react-native-gesture-handler": "~2.16.1",
"react-native-get-random-values": "~1.11.0",
Expand All @@ -48,9 +51,7 @@
"react-redux": "^9.1.0",
"styled-components": "^6.1.8",
"text-encoding": "^0.7.0",
"web-streams-polyfill": "^3.3.2",
"expo-application": "~5.9.1",
"expo-linear-gradient": "~13.0.2"
"web-streams-polyfill": "^3.3.2"
},
"devDependencies": {
"@babel/core": "^7.20.0",
Expand Down

0 comments on commit 88e48fa

Please sign in to comment.