A personal media tracker built on the AT Protocol opnshelf.xyz
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: add gradient & smaller quick add icon

+80 -42
+1 -1
AGENTS.md
··· 426 426 ### Mobile 427 427 ```bash 428 428 cd apps/mobile 429 - pnpm typecheck # TypeScript check only 429 + pnpm tsc --noEmit # TypeScript check only 430 430 ``` 431 431 432 432 **Note**: If any checks fail, fix the issues before considering the task complete.
+7 -7
apps/mobile/app/(tabs)/search.tsx
··· 139 139 > 140 140 <View style={styles.iconContainer}> 141 141 {isPending ? ( 142 - <SpinningLoader size={22} color={colors.text} /> 142 + <SpinningLoader size={16} color={colors.text} /> 143 143 ) : isWatched ? ( 144 - <Check size={22} color={colors.text} strokeWidth={2.5} /> 144 + <Check size={16} color={colors.text} strokeWidth={2.5} /> 145 145 ) : ( 146 - <Plus size={22} color={colors.text} strokeWidth={2.5} /> 146 + <Plus size={16} color={colors.text} strokeWidth={2.5} /> 147 147 )} 148 148 </View> 149 149 </AnimatedPressable> ··· 422 422 position: "absolute", 423 423 top: spacing.sm, 424 424 right: spacing.sm, 425 - width: 44, 426 - height: 44, 425 + width: 40, 426 + height: 40, 427 427 borderRadius: borderRadius.full, 428 428 backgroundColor: colors.primary, 429 429 justifyContent: "center", ··· 438 438 backgroundColor: colors.success, 439 439 }, 440 440 iconContainer: { 441 - width: 22, 442 - height: 22, 441 + width: 20, 442 + height: 20, 443 443 justifyContent: "center", 444 444 alignItems: "center", 445 445 },
+54 -34
apps/mobile/app/movie/[id].tsx
··· 13 13 import DateTimePicker, { DateTimePickerEvent } from "@react-native-community/datetimepicker"; 14 14 import { useLocalSearchParams, useRouter } from "expo-router"; 15 15 import { Image } from "expo-image"; 16 + import { LinearGradient } from "expo-linear-gradient"; 16 17 import { Ionicons } from "@expo/vector-icons"; 17 18 import { 18 19 ActivityIndicator, ··· 548 549 <Text style={[styles.sectionTitle, { color: movieColors.primary }]}> 549 550 Cast 550 551 </Text> 551 - <ScrollView 552 - horizontal 553 - showsHorizontalScrollIndicator={false} 554 - contentContainerStyle={styles.castScrollContent} 555 - > 556 - {movie.credits.cast.map((person: TmdbCastDto) => ( 557 - <TouchableOpacity 558 - key={person.id} 559 - style={styles.castCard} 560 - activeOpacity={0.8} 561 - > 562 - <View style={styles.castImageContainer}> 563 - {person.profile_path ? ( 564 - <Image 565 - source={{ uri: `https://image.tmdb.org/t/p/w185${person.profile_path}` }} 566 - style={styles.castImage} 567 - contentFit="cover" 568 - /> 569 - ) : ( 570 - <View style={styles.castImagePlaceholder}> 571 - <Text style={styles.castImagePlaceholderText}>No photo</Text> 572 - </View> 573 - )} 574 - </View> 575 - <Text style={styles.castName} numberOfLines={2}> 576 - {person.name} 577 - </Text> 578 - {person.character && ( 579 - <Text style={[styles.castCharacter, { color: movieColors.muted }]}> 580 - as {person.character} 552 + <View style={styles.castContainer}> 553 + <ScrollView 554 + horizontal 555 + showsHorizontalScrollIndicator={false} 556 + contentContainerStyle={styles.castScrollContent} 557 + > 558 + {movie.credits.cast.map((person: TmdbCastDto) => ( 559 + <TouchableOpacity 560 + key={person.id} 561 + style={styles.castCard} 562 + activeOpacity={0.8} 563 + > 564 + <View style={styles.castImageContainer}> 565 + {person.profile_path ? ( 566 + <Image 567 + source={{ uri: `https://image.tmdb.org/t/p/w185${person.profile_path}` }} 568 + style={styles.castImage} 569 + contentFit="cover" 570 + /> 571 + ) : ( 572 + <View style={styles.castImagePlaceholder}> 573 + <Text style={styles.castImagePlaceholderText}>No photo</Text> 574 + </View> 575 + )} 576 + </View> 577 + <Text style={styles.castName} numberOfLines={2}> 578 + {person.name} 581 579 </Text> 582 - )} 583 - </TouchableOpacity> 584 - ))} 585 - </ScrollView> 580 + {person.character && ( 581 + <Text style={[styles.castCharacter, { color: movieColors.muted }]}> 582 + as {person.character} 583 + </Text> 584 + )} 585 + </TouchableOpacity> 586 + ))} 587 + </ScrollView> 588 + <LinearGradient 589 + colors={["rgba(3, 7, 18, 0)", "rgba(3, 7, 18, 1)"]} 590 + start={{ x: 0, y: 0.5 }} 591 + end={{ x: 1, y: 0.5 }} 592 + style={styles.castGradient} 593 + /> 594 + </View> 586 595 </View> 587 596 )} 588 597 ··· 1056 1065 color: "#6b7280", 1057 1066 padding: 32, 1058 1067 }, 1068 + castContainer: { 1069 + position: "relative", 1070 + }, 1059 1071 castScrollContent: { 1060 1072 paddingRight: 16, 1061 1073 gap: 12, 1074 + }, 1075 + castGradient: { 1076 + position: "absolute", 1077 + right: 0, 1078 + top: 0, 1079 + bottom: 16, 1080 + width: 48, 1081 + pointerEvents: "none", 1062 1082 }, 1063 1083 castCard: { 1064 1084 width: 100,
+1
apps/mobile/package.json
··· 29 29 "expo-font": "~14.0.11", 30 30 "expo-haptics": "~15.0.8", 31 31 "expo-image": "~3.0.11", 32 + "expo-linear-gradient": "^15.0.8", 32 33 "expo-linking": "~8.0.11", 33 34 "expo-router": "~6.0.23", 34 35 "expo-secure-store": "^15.0.8",
+1
apps/mobile/tsconfig.json
··· 2 2 "extends": "expo/tsconfig.base", 3 3 "compilerOptions": { 4 4 "strict": true, 5 + "lib": ["es2022", "dom"], 5 6 "paths": { 6 7 "@/*": [ 7 8 "./*"
+16
pnpm-lock.yaml
··· 65 65 expo-image: 66 66 specifier: ~3.0.11 67 67 version: 3.0.11(expo@54.0.33)(react-native-web@0.21.2(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-native@0.81.5(@babel/core@7.28.6)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) 68 + expo-linear-gradient: 69 + specifier: ^15.0.8 70 + version: 15.0.8(expo@54.0.33)(react-native@0.81.5(@babel/core@7.28.6)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) 68 71 expo-linking: 69 72 specifier: ~8.0.11 70 73 version: 8.0.11(expo@54.0.33)(react-native@0.81.5(@babel/core@7.28.6)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) ··· 5765 5768 peerDependencies: 5766 5769 expo: '*' 5767 5770 react: '*' 5771 + 5772 + expo-linear-gradient@15.0.8: 5773 + resolution: {integrity: sha512-V2d8Wjn0VzhPHO+rrSBtcl+Fo+jUUccdlmQ6OoL9/XQB7Qk3d9lYrqKDJyccwDxmQT10JdST3Tmf2K52NLc3kw==} 5774 + peerDependencies: 5775 + expo: '*' 5776 + react: '*' 5777 + react-native: '*' 5768 5778 5769 5779 expo-linking@8.0.11: 5770 5780 resolution: {integrity: sha512-+VSaNL5om3kOp/SSKO5qe6cFgfSIWnnQDSbA7XLs3ECkYzXRquk5unxNS3pg7eK5kNUmQ4kgLI7MhTggAEUBLA==} ··· 16134 16144 dependencies: 16135 16145 expo: 54.0.33(@babel/core@7.28.6)(@expo/metro-runtime@6.1.2)(expo-router@6.0.23)(react-native@0.81.5(@babel/core@7.28.6)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) 16136 16146 react: 19.1.0 16147 + 16148 + expo-linear-gradient@15.0.8(expo@54.0.33)(react-native@0.81.5(@babel/core@7.28.6)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0): 16149 + dependencies: 16150 + expo: 54.0.33(@babel/core@7.28.6)(@expo/metro-runtime@6.1.2)(expo-router@6.0.23)(react-native@0.81.5(@babel/core@7.28.6)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) 16151 + react: 19.1.0 16152 + react-native: 0.81.5(@babel/core@7.28.6)(@types/react@19.1.17)(react@19.1.0) 16137 16153 16138 16154 expo-linking@8.0.11(expo@54.0.33)(react-native@0.81.5(@babel/core@7.28.6)(@types/react@19.1.17)(react@19.1.0))(react@19.1.0): 16139 16155 dependencies: