feat(ui): add emoji picker with FlatList virtualization and improve input components
Some checks failed
Frontend CI / build-and-push-web (push) Failing after 2m43s
Frontend CI / ota-android (push) Successful in 10m32s
Frontend CI / build-android-apk (push) Successful in 47m43s

- Add full emoji picker with virtualized FlatList to CreatePostScreen and PostDetailScreen
- Add autoExpand prop to PostMentionInput for XHS-style content area
- Improve mention item styling with @ icon and hint text
- Fix HomeScreen tab switching race condition with requestAnimationFrame
- Fix PostRepository pagination to prefer cursor over page parameter
- Fix user store imports to use explicit UserManager path
- Refactor useCurrentUser hook to use sessionStore directly
This commit is contained in:
lafay
2026-04-24 16:44:01 +08:00
parent b2c3d5e54e
commit 738e75a79d
9 changed files with 277 additions and 75 deletions

View File

@@ -13,6 +13,7 @@ import {
StyleSheet,
Platform,
} from 'react-native';
import { MaterialCommunityIcons } from '@expo/vector-icons';
import Text from '../common/Text';
import Avatar from '../common/Avatar';
@@ -35,6 +36,7 @@ interface PostMentionInputProps {
maxLength?: number;
style?: any;
minHeight?: number;
autoExpand?: boolean;
}
const PostMentionInput: React.FC<PostMentionInputProps> = ({
@@ -45,6 +47,7 @@ const PostMentionInput: React.FC<PostMentionInputProps> = ({
maxLength = 2000,
style,
minHeight = 100,
autoExpand = false,
}) => {
const colors = useAppColors();
const currentUser = useAuthStore(s => s.currentUser);
@@ -180,16 +183,23 @@ const PostMentionInput: React.FC<PostMentionInputProps> = ({
<TouchableOpacity
style={[styles.mentionItem, { borderBottomColor: colors.divider }]}
onPress={() => handleSelectMention(item)}
activeOpacity={0.7}
>
<Avatar source={item.avatar} size={32} name={item.nickname} />
<Text style={[styles.mentionName, { color: colors.text.primary }]}>
{item.nickname}
</Text>
<Avatar source={item.avatar} size={36} name={item.nickname} />
<View style={styles.mentionInfo}>
<Text style={[styles.mentionName, { color: colors.text.primary }]}>
{item.nickname}
</Text>
<Text style={[styles.mentionHint, { color: colors.text.hint }]}>
</Text>
</View>
<MaterialCommunityIcons name="at" size={18} color={colors.primary.main} />
</TouchableOpacity>
);
return (
<View style={style}>
<View style={[styles.container, style]}>
<TextInput
ref={inputRef}
value={value}
@@ -198,11 +208,15 @@ const PostMentionInput: React.FC<PostMentionInputProps> = ({
placeholderTextColor={colors.text.hint}
maxLength={maxLength}
multiline
textAlignVertical="top"
scrollEnabled={!autoExpand}
style={[
styles.input,
autoExpand && styles.inputAutoExpand,
{
color: colors.text.primary,
backgroundColor: colors.background.default,
backgroundColor: autoExpand ? 'transparent' : colors.background.default,
minHeight,
},
]}
/>
@@ -232,6 +246,9 @@ const PostMentionInput: React.FC<PostMentionInputProps> = ({
};
const styles = StyleSheet.create({
container: {
flexGrow: 1,
},
input: {
fontSize: fontSizes.md,
padding: spacing.sm,
@@ -239,6 +256,12 @@ const styles = StyleSheet.create({
minHeight: 100,
textAlignVertical: 'top' as const,
},
inputAutoExpand: {
borderRadius: 0,
paddingHorizontal: 0,
paddingTop: spacing.sm,
paddingBottom: spacing.sm,
},
mentionPanel: {
borderWidth: 1,
borderRadius: borderRadius.md,
@@ -255,9 +278,18 @@ const styles = StyleSheet.create({
paddingVertical: spacing.sm,
borderBottomWidth: StyleSheet.hairlineWidth,
},
mentionInfo: {
flex: 1,
marginLeft: spacing.sm,
justifyContent: 'center',
},
mentionName: {
fontSize: fontSizes.md,
marginLeft: spacing.sm,
fontWeight: '500',
},
mentionHint: {
fontSize: fontSizes.xs,
marginTop: 2,
},
emptyText: {
fontSize: fontSizes.sm,