Skip to content

Commit

Permalink
Merge pull request #236 from Crossbell-Box/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
dohooo authored Sep 1, 2023
2 parents a99a207 + d7029b5 commit e36825c
Show file tree
Hide file tree
Showing 32 changed files with 503 additions and 401 deletions.
5 changes: 5 additions & 0 deletions .changeset/forty-needles-compare.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"xlog": patch
---

Login directly in the introduction page.
5 changes: 5 additions & 0 deletions .changeset/gold-yaks-confess.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"xlog": patch
---

New profile page.
5 changes: 5 additions & 0 deletions .changeset/pretty-chicken-argue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"xlog": patch
---

Some style changes.
12 changes: 6 additions & 6 deletions src/components/Avatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { Circle, Text, Avatar as _Avatar } from "tamagui";
import { useNavigateToUserInfo } from "@/hooks/use-navigate-to-user-info";
import { toGateway } from "@/utils/ipfs-parser";

import { LogoResource, LogoLightResource } from "./Logo";
import { LogoBlueResource } from "./Logo";
import { XTouch } from "./XTouch";

interface Props {
Expand Down Expand Up @@ -64,7 +64,7 @@ export const Avatar: FC<Props> = (props) => {
alignItems="center"
justifyContent="center"
>
<Image source={LogoLightResource} contentFit={"contain"} style={{ height: "75%", width: "75%" }} />
<Image source={LogoBlueResource} contentFit={"contain"} style={{ height: "75%", width: "75%" }} />
</Circle>
);
}
Expand All @@ -81,11 +81,11 @@ export const Avatar: FC<Props> = (props) => {
<_Avatar
size={size}
circular
backgroundColor="white"
backgroundColor="black"
>
<_Avatar.Image src={toGateway(uri)} />
<_Avatar.Image src={toGateway(uri)}/>
<_Avatar.Fallback>
<Image source={LogoResource} contentFit={"cover"} style={styles.container} />
<Image source={LogoBlueResource} contentFit={"cover"} style={styles.container} />
</_Avatar.Fallback>
</_Avatar>
</XTouch>
Expand All @@ -95,7 +95,7 @@ export const Avatar: FC<Props> = (props) => {
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
backgroundColor: "#000",
alignItems: "center",
justifyContent: "center",
transform: [
Expand Down
27 changes: 15 additions & 12 deletions src/components/ConnectEmailButton.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import React from "react";
import { useTranslation } from "react-i18next";
import { TouchableOpacity } from "react-native-gesture-handler";

import { useConnectedAccount, useAccountState } from "@crossbell/react-account";
import { Mail } from "@tamagui/lucide-icons";
import { openAuthSessionAsync } from "expo-web-browser";
import type { ButtonProps } from "tamagui";
import { Button } from "tamagui";
import { Button, Stack, XStack, Text } from "tamagui";

import { APP_SCHEME } from "@/constants";
import { useGlobalLoading } from "@/hooks/use-global-loading";

import { Center } from "./Base/Center";

export const ConnectEmailButton = (props: ButtonProps) => {
const i18n = useTranslation();
const account = useConnectedAccount();
Expand All @@ -34,18 +37,18 @@ export const ConnectEmailButton = (props: ButtonProps) => {
if (account) return null;

return (
<Button
borderWidth={0}
pressStyle={{ opacity: 0.85 }}
color={"white"}
fontSize={"$6"}
fontWeight={"700"}
backgroundColor={"$primary"}
<TouchableOpacity
activeOpacity={0.8}
onPress={openWebPage}
icon={<Mail size={"$1.5"} />}
{...props}
>
{i18n.t("Connect Email")}
</Button>
<Stack paddingVertical="$3" borderRadius={"$5"} overflow="hidden">
<Center>
<XStack alignItems="center" gap="$2">
<Mail size={"$2"}/>
<Text fontWeight={"600"} color="$color" fontSize={"$6"}>{i18n.t("Connect with Email")}</Text>
</XStack>
</Center>
</Stack>
</TouchableOpacity>
);
};
35 changes: 20 additions & 15 deletions src/components/ConnectionButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { FC } from "react";
import { useEffect, useRef } from "react";
import { useTranslation } from "react-i18next";
import { Alert, Linking } from "react-native";
import { TouchableOpacity } from "react-native-gesture-handler";
import Animated, { FadeIn, FadeOut, FlipInXDown } from "react-native-reanimated";

import {
Expand All @@ -15,9 +16,10 @@ import { Plug, Wallet } from "@tamagui/lucide-icons";
import { useToastController } from "@tamagui/toast";
import { useWalletConnectModal } from "@walletconnect/modal-react-native";
import * as Haptics from "expo-haptics";
import { LinearGradient } from "expo-linear-gradient";
import * as Sentry from "sentry-expo";
import type { StackProps } from "tamagui";
import { Stack } from "tamagui";
import { Stack, Text, XStack } from "tamagui";

import { IS_IOS } from "@/constants";
import { useAppIsActive } from "@/hooks/use-app-state";
Expand All @@ -29,6 +31,7 @@ import { GA } from "@/utils/GA";
import type { AlertDialogInstance } from "./AlertDialog";
import { AlertDialog } from "./AlertDialog";
import { Button } from "./Base/Button";
import { Center } from "./Base/Center";
import { DelayedRender } from "./DelayRender";

interface Props extends StackProps {
Expand Down Expand Up @@ -152,20 +155,22 @@ function ConnectBtn({ navigateToLogin }: { navigateToLogin: boolean }) {
};

return (
<Animated.View>
<Button
borderWidth={0}
pressStyle={{ opacity: 0.85 }}
color={"white"}
fontSize={"$6"}
fontWeight={"700"}
backgroundColor={"$primary"}
onPress={handleConnect}
icon={navigateToLogin ? <Plug size="$1.5" /> : <Wallet size={"$1.5"} />}
>
{i18n.t(navigateToLogin ? "Connect" : "Connect Wallet")}
</Button>
</Animated.View>
<TouchableOpacity activeOpacity={0.8} onPress={handleConnect}>
<Stack paddingVertical="$3" borderRadius={"$5"} overflow="hidden">
<LinearGradient
colors={["#30a19b", "#2875bf"]}
style={{ position: "absolute", width: "100%", top: 0, bottom: 0 }}
start={{ x: 0, y: 0.5 }}
end={{ x: 1, y: 0.5 }}
/>
<Center>
<XStack alignItems="center" gap="$2">
<Wallet size={"$2"}/>
<Text fontWeight={"600"} color="$color" fontSize={"$6"}>{i18n.t("Connect with Wallet")}</Text>
</XStack>
</Center>
</Stack>
</TouchableOpacity>
);
}

Expand Down
3 changes: 2 additions & 1 deletion src/components/FeedList/FeedListItem/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ export const FeedListItem: FC<Props> = (props) => {
{
characterId: note.characterId,
noteId: note.noteId,
coverImageIndex: placeholderBgIndex,
placeholderCoverImageIndex: placeholderBgIndex,
coverImage,
},
);
}, [note]);
Expand Down
140 changes: 15 additions & 125 deletions src/components/FeedList/index.tsx
Original file line number Diff line number Diff line change
@@ -1,138 +1,28 @@
import type { FC } from "react";
import { useEffect, useMemo, useRef } from "react";
import type { useAnimatedScrollHandler } from "react-native-reanimated";
import Animated from "react-native-reanimated";

import type { ContentStyle, MasonryFlashListProps, MasonryFlashListRef } from "@shopify/flash-list";
import { SizableText, Spinner, Stack, useWindowDimensions } from "tamagui";

import { useCharacterId } from "@/hooks/use-character-id";
import type { FeedType, SearchType } from "@/models/home.model";
import { useGetFeed } from "@/queries/home";
import type { ExpandedNote } from "@/types/crossbell";
import { debounce } from "@/utils/debounce";
import { GA } from "@/utils/GA";

import { FeedListItem } from "./FeedListItem";
import { Skeleton } from "./Skeleton";
import type { Props as FeedListProps } from "./useFeedList";
import { useFeedList } from "./useFeedList";

import topics from "../../data/topics.json";
import { Center } from "../Base/Center";
import { FillSpinner } from "../FillSpinner";
import { MasonryFlashList } from "../MasonryFlashList";
import { MeasureContainer } from "../utils/MeasureContainer";

export interface Props {
onScroll?: ReturnType<typeof useAnimatedScrollHandler>
type?: FeedType
noteIds?: string[]
/**
* @default 7
* */
daysInterval?: number
searchKeyword?: string
tag?: string
topic?: string
searchType?: SearchType
contentContainerStyle?: ContentStyle
}

export const FeedList: FC<Props> = (props) => {
const { type, searchType, searchKeyword, contentContainerStyle = {}, tag, topic, noteIds, daysInterval = 7, onScroll } = props;
const characterId = useCharacterId();
const gaLog = debounce(() => GA.logSearch({ search_term: searchKeyword }), 2000);
const { width } = useWindowDimensions();
const listRef = useRef<MasonryFlashListRef<ExpandedNote>>(null);
import { TabMasonryFlashList } from "../TabMasonryFlashList";

useEffect(() => {
typeof searchKeyword === "string" && gaLog();
}, [searchKeyword]);
interface MasonryProps extends FeedListProps {}

useEffect(() => {
listRef.current?.scrollToOffset({ offset: 0, animated: false });
}, [type, daysInterval]);
export const MasonryFeedList: FC<MasonryProps> = (props) => {
const _props = useFeedList(props);

const queryParams = useMemo(() => ({
type,
limit: 30,
characterId,
noteIds,
daysInterval,
searchKeyword,
searchType,
tag,
topicIncludeKeywords: topic
? topics.find(t => t.name === topic)?.includeKeywords
: undefined,
}), [
type,
characterId,
noteIds,
daysInterval,
searchKeyword,
searchType,
tag,
topic,
]);

// TODO
const feed = useGetFeed(queryParams);
const feedList = useMemo(() => (feed.data?.pages?.flatMap(page => page?.list) || []), [feed.data?.pages]);
return <MasonryFlashList<ExpandedNote> {..._props}/>;
};

return (
<MasonryFlashList<ExpandedNote>
data={feedList}
ref={listRef}
numColumns={2}
keyExtractor={post => `${post.characterId}-${post.noteId}`}
renderItem={({ item, index }) => (
<FeedListItem width={width / 2 - 12} key={index} note={item} searchKeyword={searchKeyword}/>
)}
ListEmptyComponent={(
<Stack>
{
feed.isFetching
? <Skeleton itemWidth={width / 2 - 12}/>
: (
<Center flex={1}>
<SizableText color={"$colorSubtitle"}>
There are no posts yet.
</SizableText>
</Center>
)
}
</Stack>
)}
bounces
estimatedItemSize={251}
ListFooterComponent={feed.isFetchingNextPage && <Spinner paddingBottom="$5"/>}
contentContainerStyle={{ ...contentContainerStyle, paddingHorizontal: 4 }}
scrollEventThrottle={16}
onScroll={onScroll}
onEndReachedThreshold={2}
onEndReached={() => {
if (
feedList.length === 0
|| feed.isFetchingNextPage
|| feed.hasNextPage === false
)
return;
interface TabMasonryProps extends FeedListProps {
index: number
characterId: number
}

GA.logEvent("feed_list_view", {
feed_length: feedList.length,
feed_type: queryParams.type,
query_limit: queryParams.limit,
character_id: queryParams.characterId,
note_ids: queryParams.noteIds,
days_interval: queryParams.daysInterval,
search_keyword: queryParams.searchKeyword,
search_type: queryParams.searchType,
tag: queryParams.tag,
topic_include_keywords: queryParams.topicIncludeKeywords,
});
export const TabMasonryFeedList: FC<TabMasonryProps> = (props) => {
const _props = useFeedList(props);

feed?.fetchNextPage?.();
}}
/>
);
return <TabMasonryFlashList<ExpandedNote> {..._props}/>;
};
Loading

0 comments on commit e36825c

Please sign in to comment.