Initial commit: expo-popcore project
This commit is contained in:
135
components/profile/profile-screen.tsx
Normal file
135
components/profile/profile-screen.tsx
Normal file
@@ -0,0 +1,135 @@
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import { StyleSheet, View, useWindowDimensions, type ImageSourcePropType } from 'react-native';
|
||||
import { useAuth } from '@/hooks/use-auth';
|
||||
import { useBalance } from '@/hooks/use-balance';
|
||||
import { useProfileData } from '@/hooks/use-profile-data';
|
||||
import { PROFILE_THEME } from '@/theme/profile';
|
||||
import { createStats, deriveAvatarSource, deriveDisplayName } from '@/utils/profile-data';
|
||||
import { ContentGallery } from './content-gallery';
|
||||
import { ContentTabs } from './content-tabs';
|
||||
import { Divider } from './divider';
|
||||
import { ProfileEditModal } from './profile-edit-modal';
|
||||
import { ProfileHeader } from './profile-header';
|
||||
import { ProfileIdentity } from './profile-identity';
|
||||
import { Page } from '../sker/page';
|
||||
|
||||
type TabKey = 'all' | 'image' | 'video';
|
||||
type BillingMode = 'monthly' | 'lifetime';
|
||||
|
||||
export function ProfileScreen() {
|
||||
const { user } = useAuth();
|
||||
const { balance } = useBalance();
|
||||
const { width } = useWindowDimensions();
|
||||
const [billingMode, setBillingMode] = useState<BillingMode>('monthly');
|
||||
const [activeTab, setActiveTab] = useState<TabKey>('all');
|
||||
const [isEditingIdentity, setIsEditingIdentity] = useState(false);
|
||||
const [editedIdentity, setEditedIdentity] = useState<{
|
||||
name?: string;
|
||||
avatar?: ImageSourcePropType;
|
||||
} | null>(null);
|
||||
|
||||
const {
|
||||
generations,
|
||||
isRefreshing,
|
||||
isLoadingMore,
|
||||
hasMore,
|
||||
isTabSwitching,
|
||||
handleRefresh,
|
||||
handleLoadMore,
|
||||
} = useProfileData(activeTab);
|
||||
|
||||
const isSmallScreen = width < PROFILE_THEME.breakpoints.small;
|
||||
const avatarSize = isSmallScreen
|
||||
? PROFILE_THEME.avatar.size.small
|
||||
: PROFILE_THEME.avatar.size.large;
|
||||
|
||||
const displayNameFromUser = deriveDisplayName(user) ?? 'prairie_pufferfish_the';
|
||||
const avatarSource = deriveAvatarSource(user);
|
||||
const creditBalance = balance.remainingTokenBalance;
|
||||
const stats = createStats(user);
|
||||
|
||||
const presentedDisplayName = editedIdentity?.name ?? displayNameFromUser;
|
||||
const presentedAvatar = editedIdentity?.avatar ?? avatarSource;
|
||||
|
||||
const headerContainerStyle = useMemo(
|
||||
() => ({
|
||||
paddingHorizontal: 0,
|
||||
paddingBottom: 0,
|
||||
}),
|
||||
[]
|
||||
);
|
||||
|
||||
const headerComponent = useMemo(
|
||||
() => (
|
||||
<View style={headerContainerStyle}>
|
||||
<ProfileHeader
|
||||
billingMode={billingMode}
|
||||
onChangeBilling={setBillingMode}
|
||||
credits={creditBalance}
|
||||
/>
|
||||
|
||||
<ProfileIdentity
|
||||
displayName={presentedDisplayName}
|
||||
avatarSource={presentedAvatar}
|
||||
avatarSize={avatarSize}
|
||||
stats={stats}
|
||||
onEdit={() => setIsEditingIdentity(true)}
|
||||
/>
|
||||
|
||||
<Divider />
|
||||
|
||||
<ContentTabs
|
||||
activeTab={activeTab}
|
||||
onChangeTab={setActiveTab}
|
||||
isLoading={isTabSwitching}
|
||||
/>
|
||||
|
||||
<Divider />
|
||||
</View>
|
||||
),
|
||||
[
|
||||
headerContainerStyle,
|
||||
billingMode,
|
||||
creditBalance,
|
||||
presentedDisplayName,
|
||||
presentedAvatar,
|
||||
avatarSize,
|
||||
stats,
|
||||
activeTab,
|
||||
isTabSwitching,
|
||||
]
|
||||
);
|
||||
|
||||
return (
|
||||
<Page>
|
||||
<ContentGallery
|
||||
generations={generations}
|
||||
isRefreshing={isRefreshing}
|
||||
onRefresh={handleRefresh}
|
||||
isLoadingMore={isLoadingMore}
|
||||
hasMore={hasMore}
|
||||
onLoadMore={handleLoadMore}
|
||||
ListHeaderComponent={headerComponent}
|
||||
/>
|
||||
|
||||
<ProfileEditModal
|
||||
visible={isEditingIdentity}
|
||||
avatarSource={presentedAvatar}
|
||||
initialName={presentedDisplayName}
|
||||
onClose={() => setIsEditingIdentity(false)}
|
||||
onSave={({ name, avatar }) => {
|
||||
setEditedIdentity({ name, avatar });
|
||||
setIsEditingIdentity(false);
|
||||
}}
|
||||
/>
|
||||
</Page>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
flexContainer: {
|
||||
flex: 1,
|
||||
},
|
||||
});
|
||||
|
||||
export default ProfileScreen;
|
||||
Reference in New Issue
Block a user