expo-popcore-old/components/profile/profile-screen.tsx

136 lines
3.7 KiB
TypeScript

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;