diff --git a/eslint.config.mjs b/eslint.config.mjs index f9a291fe..da66be07 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -15,7 +15,7 @@ import unusedImports from 'eslint-plugin-unused-imports'; export default [ { files: ['**/*.{js,mjs,cjs,ts,jsx,tsx}'] }, { - ignores: ['**/node_modules/**', '**/build/**', '**/dist/**'], + ignores: ['**/node_modules/**', '**/build/**', '**/dist/**', '**/.next/**'], }, { languageOptions: { globals: globals.node } }, { languageOptions: { globals: globals.browser } }, diff --git a/package.json b/package.json index a21b6e29..e61fa696 100644 --- a/package.json +++ b/package.json @@ -17,8 +17,8 @@ "build:react-sdk": "yarn workspace @stream-io/feeds-react-native-sdk run build", "build:react-tutorial": "yarn build:client && yarn build:react-sdk && yarn workspace stream-feeds-react-tutorial run build", "clean:all": "yarn workspaces foreach -vt run clean", - "lint:all": "eslint --max-warnings=0 --cache 'packages/**/*.{ts,tsx}'", - "lint:all:fix": "eslint --max-warnings=0 'packages/**/*.{ts,tsx}' --fix", + "lint:all": "eslint --max-warnings=0 --cache '**/*.{ts,tsx}'", + "lint:all:fix": "eslint --max-warnings=0 '**/*.{ts,tsx}' --fix", "test:ci:all": "yarn workspaces foreach -vt run test-ci", "test:ci:libs": "yarn workspaces foreach -vt --no-private run test-ci", "test:docs-snippets": "yarn workspaces foreach -vt --no-private run test-docs-snippets", diff --git a/packages/feeds-client/src/bindings/react/hooks/feed-state-hooks/useOwnCapabilities.ts b/packages/feeds-client/src/bindings/react/hooks/feed-state-hooks/useOwnCapabilities.ts index fbb92a19..5b42bf71 100644 --- a/packages/feeds-client/src/bindings/react/hooks/feed-state-hooks/useOwnCapabilities.ts +++ b/packages/feeds-client/src/bindings/react/hooks/feed-state-hooks/useOwnCapabilities.ts @@ -6,11 +6,11 @@ import { useCallback } from 'react'; const stableEmptyArray: readonly FeedOwnCapability[] = []; -export const useOwnCapabilities = (feedFromProps?: Feed) => { +export const useOwnCapabilities = (feedFromProps?: Feed | string) => { const client = useFeedsClient(); const feedFromContext = useFeedContext(); const feed = feedFromProps ?? feedFromContext; - const fid = feed?.feed; + const fid = typeof feed === 'string' ? feed : feed?.feed; const selector = useCallback( (currentState: FeedsClientState) => { diff --git a/sample-apps/react-native/ExpoTikTokApp/app/_layout.tsx b/sample-apps/react-native/ExpoTikTokApp/app/_layout.tsx index 30f6113f..918da3ff 100644 --- a/sample-apps/react-native/ExpoTikTokApp/app/_layout.tsx +++ b/sample-apps/react-native/ExpoTikTokApp/app/_layout.tsx @@ -14,8 +14,9 @@ import 'react-native-reanimated'; import { StreamFeeds } from '@stream-io/feeds-react-native-sdk'; import LoginScreen from '@/components/LoginScreen'; +import type { + LocalUser} from '@/contexts/UserContext'; import { - LocalUser, UserContextProvider, useUserContext, } from '@/contexts/UserContext'; diff --git a/sample-apps/react-native/ExpoTikTokApp/components/activity-composer/ActivityComposer.tsx b/sample-apps/react-native/ExpoTikTokApp/components/activity-composer/ActivityComposer.tsx index a071e636..a13f00ae 100644 --- a/sample-apps/react-native/ExpoTikTokApp/components/activity-composer/ActivityComposer.tsx +++ b/sample-apps/react-native/ExpoTikTokApp/components/activity-composer/ActivityComposer.tsx @@ -2,12 +2,13 @@ import React, { useCallback, useMemo, useState } from 'react'; import { View, ScrollView, Text, StyleSheet, Pressable } from 'react-native'; import * as ImagePicker from 'expo-image-picker'; -import { +import type { Attachment, CreateFeedsBatchResponse, + StreamFile} from '@stream-io/feeds-react-native-sdk'; +import { isImageFile, isVideoFile, - StreamFile, useFeedContext, useFeedsClient, } from '@stream-io/feeds-react-native-sdk'; diff --git a/sample-apps/react-native/ExpoTikTokApp/components/activity-pager/Pager.tsx b/sample-apps/react-native/ExpoTikTokApp/components/activity-pager/Pager.tsx index f7272dbe..6c1aa38b 100644 --- a/sample-apps/react-native/ExpoTikTokApp/components/activity-pager/Pager.tsx +++ b/sample-apps/react-native/ExpoTikTokApp/components/activity-pager/Pager.tsx @@ -1,13 +1,15 @@ import { useFeedActivities } from '@stream-io/feeds-react-native-sdk'; import React, { useEffect, useRef, useState } from 'react'; import { useStableCallback } from '@/hooks/useStableCallback'; +import type { + NativeScrollEvent, + NativeSyntheticEvent} from 'react-native'; import { Dimensions, - NativeScrollEvent, - NativeSyntheticEvent, Platform, } from 'react-native'; -import { FlashList, FlashListRef } from '@shopify/flash-list'; +import type { FlashListRef } from '@shopify/flash-list'; +import { FlashList } from '@shopify/flash-list'; import type { ActivityResponse } from '@stream-io/feeds-react-native-sdk'; import { ActivityPagerContextProvider } from '@/contexts/ActivityPagerContext'; import { PagerItem } from '@/components/activity-pager/PagerItem'; diff --git a/sample-apps/react-native/ExpoTikTokApp/components/activity-section-list/ActivityAction.tsx b/sample-apps/react-native/ExpoTikTokApp/components/activity-section-list/ActivityAction.tsx index ad9006c1..361d4bde 100644 --- a/sample-apps/react-native/ExpoTikTokApp/components/activity-section-list/ActivityAction.tsx +++ b/sample-apps/react-native/ExpoTikTokApp/components/activity-section-list/ActivityAction.tsx @@ -2,7 +2,7 @@ import { Platform, TouchableOpacity } from 'react-native'; import { Ionicons } from '@expo/vector-icons'; import { useStableCallback } from '@/hooks/useStableCallback'; import { openSheetWith } from '@/store/bottom-sheet-state-store'; -import { ActivityResponse } from '@stream-io/feeds-react-native-sdk'; +import type { ActivityResponse } from '@stream-io/feeds-react-native-sdk'; import { useRouter } from 'expo-router'; export const ActivityAction = ({ diff --git a/sample-apps/react-native/ExpoTikTokApp/components/activity-section-list/ActivitySectionList.tsx b/sample-apps/react-native/ExpoTikTokApp/components/activity-section-list/ActivitySectionList.tsx index ee9956a8..6b5e810c 100644 --- a/sample-apps/react-native/ExpoTikTokApp/components/activity-section-list/ActivitySectionList.tsx +++ b/sample-apps/react-native/ExpoTikTokApp/components/activity-section-list/ActivitySectionList.tsx @@ -7,7 +7,6 @@ import { ActivityIndicator, FlatList, StyleSheet } from 'react-native'; import { Activity } from '@/components/activity-section-list/Activity'; import { useCallback } from 'react'; import { LoadingIndicator, ErrorIndicator } from '@/components/indicators'; -import { useStableCallback } from '@/hooks/useStableCallback'; import { View } from '@/components/common/Themed'; const renderItem = ({ diff --git a/sample-apps/react-native/ExpoTikTokApp/components/bottom-sheet/ActivitySheet.tsx b/sample-apps/react-native/ExpoTikTokApp/components/bottom-sheet/ActivitySheet.tsx index ddc77b71..a0fde797 100644 --- a/sample-apps/react-native/ExpoTikTokApp/components/bottom-sheet/ActivitySheet.tsx +++ b/sample-apps/react-native/ExpoTikTokApp/components/bottom-sheet/ActivitySheet.tsx @@ -1,7 +1,8 @@ import React, { useMemo } from 'react'; import { Ionicons } from '@expo/vector-icons'; +import type { + ActivityResponse} from '@stream-io/feeds-react-native-sdk'; import { - ActivityResponse, useClientConnectedUser, useFeedsClient, } from '@stream-io/feeds-react-native-sdk'; diff --git a/sample-apps/react-native/ExpoTikTokApp/components/bottom-sheet/BottomSheet.tsx b/sample-apps/react-native/ExpoTikTokApp/components/bottom-sheet/BottomSheet.tsx index 4c61b353..c43a1f79 100644 --- a/sample-apps/react-native/ExpoTikTokApp/components/bottom-sheet/BottomSheet.tsx +++ b/sample-apps/react-native/ExpoTikTokApp/components/bottom-sheet/BottomSheet.tsx @@ -1,4 +1,5 @@ -import React, { PropsWithChildren, useEffect, useMemo, useRef } from 'react'; +import type { PropsWithChildren} from 'react'; +import React, { useEffect, useMemo, useRef } from 'react'; import { Dimensions, StyleSheet, @@ -6,10 +7,11 @@ import { Pressable, Platform, } from 'react-native'; +import type { + GestureType} from 'react-native-gesture-handler'; import { Gesture, - GestureDetector, - GestureType, + GestureDetector } from 'react-native-gesture-handler'; import Animated, { useSharedValue, diff --git a/sample-apps/react-native/ExpoTikTokApp/components/bottom-sheet/CommentSheet.tsx b/sample-apps/react-native/ExpoTikTokApp/components/bottom-sheet/CommentSheet.tsx index 5f053b34..28499003 100644 --- a/sample-apps/react-native/ExpoTikTokApp/components/bottom-sheet/CommentSheet.tsx +++ b/sample-apps/react-native/ExpoTikTokApp/components/bottom-sheet/CommentSheet.tsx @@ -1,7 +1,8 @@ import { useBottomSheetState } from '@/hooks/useBottomSheetState'; import { Alert } from 'react-native'; +import type { + CommentResponse} from '@stream-io/feeds-react-native-sdk'; import { - CommentResponse, useClientConnectedUser, useFeedsClient, } from '@stream-io/feeds-react-native-sdk'; diff --git a/sample-apps/react-native/ExpoTikTokApp/components/bottom-sheet/SheetList.tsx b/sample-apps/react-native/ExpoTikTokApp/components/bottom-sheet/SheetList.tsx index 044335b5..45a0a07c 100644 --- a/sample-apps/react-native/ExpoTikTokApp/components/bottom-sheet/SheetList.tsx +++ b/sample-apps/react-native/ExpoTikTokApp/components/bottom-sheet/SheetList.tsx @@ -1,7 +1,8 @@ -import { ReactElement } from 'react'; +import type { ReactElement } from 'react'; import { FlatList, Platform, StyleSheet, TouchableOpacity } from 'react-native'; import { Text } from '@/components/common/Themed'; -import { StableCallback, useStableCallback } from '@/hooks/useStableCallback'; +import type { StableCallback} from '@/hooks/useStableCallback'; +import { useStableCallback } from '@/hooks/useStableCallback'; import { closeSheet, setHeight } from '@/store/bottom-sheet-state-store'; type ActionType = () => void | Promise; diff --git a/sample-apps/react-native/ExpoTikTokApp/components/buttons/NavigationBackButton.tsx b/sample-apps/react-native/ExpoTikTokApp/components/buttons/NavigationBackButton.tsx index 81261b2a..9a855cbb 100644 --- a/sample-apps/react-native/ExpoTikTokApp/components/buttons/NavigationBackButton.tsx +++ b/sample-apps/react-native/ExpoTikTokApp/components/buttons/NavigationBackButton.tsx @@ -4,7 +4,8 @@ import Ionicons from '@expo/vector-icons/Ionicons'; import Colors from '@/constants/Colors'; import React from 'react'; import { useColorScheme } from 'react-native'; -import { StableCallback, useStableCallback } from '@/hooks/useStableCallback'; +import type { StableCallback} from '@/hooks/useStableCallback'; +import { useStableCallback } from '@/hooks/useStableCallback'; type CallbackType = () => void | Promise; diff --git a/sample-apps/react-native/ExpoTikTokApp/components/comments/CommentInput.tsx b/sample-apps/react-native/ExpoTikTokApp/components/comments/CommentInput.tsx index 707e3424..d8758d7d 100644 --- a/sample-apps/react-native/ExpoTikTokApp/components/comments/CommentInput.tsx +++ b/sample-apps/react-native/ExpoTikTokApp/components/comments/CommentInput.tsx @@ -2,7 +2,6 @@ import React, { useEffect, useRef, useState } from 'react'; import { View, StyleSheet, - TextInput, Image, KeyboardAvoidingView, Platform, diff --git a/sample-apps/react-native/ExpoTikTokApp/components/common/Bookmark.tsx b/sample-apps/react-native/ExpoTikTokApp/components/common/Bookmark.tsx index 7a3cce92..f10d2f1c 100644 --- a/sample-apps/react-native/ExpoTikTokApp/components/common/Bookmark.tsx +++ b/sample-apps/react-native/ExpoTikTokApp/components/common/Bookmark.tsx @@ -1,8 +1,9 @@ import { Ionicons } from '@expo/vector-icons'; import { TouchableOpacity } from 'react-native'; import React from 'react'; +import type { + ActivityResponse} from '@stream-io/feeds-react-native-sdk'; import { - ActivityResponse, useFeedsClient, } from '@stream-io/feeds-react-native-sdk'; import { useStableCallback } from '@/hooks/useStableCallback'; diff --git a/sample-apps/react-native/ExpoTikTokApp/components/common/LocationPreview.tsx b/sample-apps/react-native/ExpoTikTokApp/components/common/LocationPreview.tsx index 17aafe4a..65cf4536 100644 --- a/sample-apps/react-native/ExpoTikTokApp/components/common/LocationPreview.tsx +++ b/sample-apps/react-native/ExpoTikTokApp/components/common/LocationPreview.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { Text, StyleSheet, Pressable } from 'react-native'; import { Ionicons } from '@expo/vector-icons'; -import { Place } from '@/components/search/PlaceSearchDropdown'; +import type { Place } from '@/components/search/PlaceSearchDropdown'; import { useRouter } from 'expo-router'; import { mapApiKey } from '@/constants/stream'; diff --git a/sample-apps/react-native/ExpoTikTokApp/components/common/Share.tsx b/sample-apps/react-native/ExpoTikTokApp/components/common/Share.tsx index 55dfd181..80c248ac 100644 --- a/sample-apps/react-native/ExpoTikTokApp/components/common/Share.tsx +++ b/sample-apps/react-native/ExpoTikTokApp/components/common/Share.tsx @@ -1,11 +1,10 @@ import { Ionicons } from '@expo/vector-icons'; import { Share, TouchableOpacity } from 'react-native'; import React from 'react'; -import { - Attachment, - isImageFile, - isVideoFile, -} from '@stream-io/feeds-react-native-sdk'; +import type { + Attachment} from '@stream-io/feeds-react-native-sdk'; + + import { useStableCallback } from '@/hooks/useStableCallback'; const pretext = 'Check out this cool'; diff --git a/sample-apps/react-native/ExpoTikTokApp/components/common/autocomplete-input/AutocompleteInput.tsx b/sample-apps/react-native/ExpoTikTokApp/components/common/autocomplete-input/AutocompleteInput.tsx index 4d9a799c..0508c097 100644 --- a/sample-apps/react-native/ExpoTikTokApp/components/common/autocomplete-input/AutocompleteInput.tsx +++ b/sample-apps/react-native/ExpoTikTokApp/components/common/autocomplete-input/AutocompleteInput.tsx @@ -1,11 +1,12 @@ import React, { useEffect, useMemo, useRef, useState } from 'react'; +import type { + NativeSyntheticEvent, + TextInputSelectionChangeEventData, + TextInputProps} from 'react-native'; import { StyleSheet, TextInput, View, - NativeSyntheticEvent, - TextInputSelectionChangeEventData, - TextInputProps, Platform, } from 'react-native'; import { AutocompleteSearch } from '@/components/common/autocomplete-input/AutocompleteSearch'; @@ -14,8 +15,9 @@ import { useSearchContext, useSearchResult, } from '@stream-io/feeds-react-native-sdk'; +import type { + Suggestion} from '@/components/common/autocomplete-input/SuggestionsList'; import { - Suggestion, SuggestionsList, } from '@/components/common/autocomplete-input/SuggestionsList'; import { useStableCallback } from '@/hooks/useStableCallback'; diff --git a/sample-apps/react-native/ExpoTikTokApp/components/common/autocomplete-input/AutocompleteSearch.tsx b/sample-apps/react-native/ExpoTikTokApp/components/common/autocomplete-input/AutocompleteSearch.tsx index 4b724428..dea7cbc4 100644 --- a/sample-apps/react-native/ExpoTikTokApp/components/common/autocomplete-input/AutocompleteSearch.tsx +++ b/sample-apps/react-native/ExpoTikTokApp/components/common/autocomplete-input/AutocompleteSearch.tsx @@ -5,7 +5,8 @@ import { useFeedsClient, UserSearchSource, } from '@stream-io/feeds-react-native-sdk'; -import { PropsWithChildren, useMemo } from 'react'; +import type { PropsWithChildren} from 'react'; +import { useMemo } from 'react'; export const AutocompleteSearch = ({ children }: PropsWithChildren) => { const client = useFeedsClient(); diff --git a/sample-apps/react-native/ExpoTikTokApp/components/common/autocomplete-input/AutocompleteSearchResults.tsx b/sample-apps/react-native/ExpoTikTokApp/components/common/autocomplete-input/AutocompleteSearchResults.tsx index eadd97c4..e5fa5661 100644 --- a/sample-apps/react-native/ExpoTikTokApp/components/common/autocomplete-input/AutocompleteSearchResults.tsx +++ b/sample-apps/react-native/ExpoTikTokApp/components/common/autocomplete-input/AutocompleteSearchResults.tsx @@ -2,7 +2,8 @@ import { StreamSearchResults, useSearchContext, useSearchSources, } from '@stream-io/feeds-react-native-sdk'; -import { PropsWithChildren, useEffect, useMemo } from 'react'; +import type { PropsWithChildren} from 'react'; +import { useEffect, useMemo } from 'react'; export const AutocompleteSearchResults = ({ children }: PropsWithChildren) => { const searchController = useSearchContext(); diff --git a/sample-apps/react-native/ExpoTikTokApp/components/common/autocomplete-input/SuggestionsList.tsx b/sample-apps/react-native/ExpoTikTokApp/components/common/autocomplete-input/SuggestionsList.tsx index 7e23bacf..26e31793 100644 --- a/sample-apps/react-native/ExpoTikTokApp/components/common/autocomplete-input/SuggestionsList.tsx +++ b/sample-apps/react-native/ExpoTikTokApp/components/common/autocomplete-input/SuggestionsList.tsx @@ -1,4 +1,4 @@ -import { Feed, User } from '@stream-io/feeds-react-native-sdk'; +import type { Feed, User } from '@stream-io/feeds-react-native-sdk'; import { useSearchResultsContext } from '@stream-io/feeds-react-native-sdk'; import { Image, diff --git a/sample-apps/react-native/ExpoTikTokApp/components/common/tokenized-text/AnnotatedText.tsx b/sample-apps/react-native/ExpoTikTokApp/components/common/tokenized-text/AnnotatedText.tsx index 7a39cfa4..487d3eb6 100644 --- a/sample-apps/react-native/ExpoTikTokApp/components/common/tokenized-text/AnnotatedText.tsx +++ b/sample-apps/react-native/ExpoTikTokApp/components/common/tokenized-text/AnnotatedText.tsx @@ -1,6 +1,6 @@ -import { TextProps } from 'react-native'; +import type { TextProps } from 'react-native'; import { useMemo } from 'react'; -import { CommentParent } from '@stream-io/feeds-react-native-sdk'; +import type { CommentParent } from '@stream-io/feeds-react-native-sdk'; import { TokenizedText } from '@/components/common/tokenized-text/TokenizedText'; import { useMentionAnnotations } from '@/components/common/tokenized-text/hooks/useMentionAnnotations'; import { useHashtagAnnotations } from '@/components/common/tokenized-text/hooks/useHashtagAnnotations'; diff --git a/sample-apps/react-native/ExpoTikTokApp/components/common/tokenized-text/MentionText.tsx b/sample-apps/react-native/ExpoTikTokApp/components/common/tokenized-text/MentionText.tsx index 93b9d0f9..67b5edd4 100644 --- a/sample-apps/react-native/ExpoTikTokApp/components/common/tokenized-text/MentionText.tsx +++ b/sample-apps/react-native/ExpoTikTokApp/components/common/tokenized-text/MentionText.tsx @@ -1,6 +1,6 @@ -import { TextProps } from 'react-native'; +import type { TextProps } from 'react-native'; import { useMemo } from 'react'; -import { CommentParent } from '@stream-io/feeds-react-native-sdk'; +import type { CommentParent } from '@stream-io/feeds-react-native-sdk'; import { TokenizedText } from '@/components/common/tokenized-text/TokenizedText'; import { useMentionAnnotations } from '@/components/common/tokenized-text/hooks/useMentionAnnotations'; diff --git a/sample-apps/react-native/ExpoTikTokApp/components/common/tokenized-text/TokenizedText.tsx b/sample-apps/react-native/ExpoTikTokApp/components/common/tokenized-text/TokenizedText.tsx index 278967dd..244b4945 100644 --- a/sample-apps/react-native/ExpoTikTokApp/components/common/tokenized-text/TokenizedText.tsx +++ b/sample-apps/react-native/ExpoTikTokApp/components/common/tokenized-text/TokenizedText.tsx @@ -1,5 +1,6 @@ import React, { useMemo } from 'react'; -import { Text, TextProps } from 'react-native'; +import type { TextProps } from 'react-native'; +import { Text } from 'react-native'; export type TokenizerConfig = { matching: string; diff --git a/sample-apps/react-native/ExpoTikTokApp/components/common/tokenized-text/hooks/useMentionAnnotations.tsx b/sample-apps/react-native/ExpoTikTokApp/components/common/tokenized-text/hooks/useMentionAnnotations.tsx index 9949ec15..dda55f20 100644 --- a/sample-apps/react-native/ExpoTikTokApp/components/common/tokenized-text/hooks/useMentionAnnotations.tsx +++ b/sample-apps/react-native/ExpoTikTokApp/components/common/tokenized-text/hooks/useMentionAnnotations.tsx @@ -2,7 +2,7 @@ import { useRouter } from 'expo-router'; import { useCallback, useMemo } from 'react'; import { useStableCallback } from '@/hooks/useStableCallback'; import { MentionPreview } from '@/components/mentions/MentionPreview'; -import { CommentParent } from '@stream-io/feeds-react-native-sdk'; +import type { CommentParent } from '@stream-io/feeds-react-native-sdk'; export const useMentionAnnotations = ({ entity, diff --git a/sample-apps/react-native/ExpoTikTokApp/components/follows/FollowButton.tsx b/sample-apps/react-native/ExpoTikTokApp/components/follows/FollowButton.tsx index 504f5050..e9373bfb 100644 --- a/sample-apps/react-native/ExpoTikTokApp/components/follows/FollowButton.tsx +++ b/sample-apps/react-native/ExpoTikTokApp/components/follows/FollowButton.tsx @@ -1,4 +1,4 @@ -import { Feed, FollowResponse } from '@stream-io/feeds-react-native-sdk'; +import type { Feed, FollowResponse } from '@stream-io/feeds-react-native-sdk'; import { useOwnFollows } from '@stream-io/feeds-react-native-sdk'; import React, { useMemo } from 'react'; import { StyleSheet, TouchableOpacity } from 'react-native'; diff --git a/sample-apps/react-native/ExpoTikTokApp/components/follows/Followers.tsx b/sample-apps/react-native/ExpoTikTokApp/components/follows/Followers.tsx index 127ff310..207bef14 100644 --- a/sample-apps/react-native/ExpoTikTokApp/components/follows/Followers.tsx +++ b/sample-apps/react-native/ExpoTikTokApp/components/follows/Followers.tsx @@ -1,6 +1,7 @@ import { useEffect, useMemo } from 'react'; +import type { + FollowResponse} from '@stream-io/feeds-react-native-sdk'; import { - FollowResponse, useClientConnectedUser, useFeedsClient, useFollowers, diff --git a/sample-apps/react-native/ExpoTikTokApp/components/follows/Following.tsx b/sample-apps/react-native/ExpoTikTokApp/components/follows/Following.tsx index 92bfd5d0..a02336be 100644 --- a/sample-apps/react-native/ExpoTikTokApp/components/follows/Following.tsx +++ b/sample-apps/react-native/ExpoTikTokApp/components/follows/Following.tsx @@ -1,6 +1,7 @@ import { useEffect, useMemo } from 'react'; +import type { + FollowResponse} from '@stream-io/feeds-react-native-sdk'; import { - FollowResponse, useClientConnectedUser, useFeedsClient, useFollowing, diff --git a/sample-apps/react-native/ExpoTikTokApp/components/follows/FollowsWrapper.tsx b/sample-apps/react-native/ExpoTikTokApp/components/follows/FollowsWrapper.tsx index 2b49ed2f..9e39c972 100644 --- a/sample-apps/react-native/ExpoTikTokApp/components/follows/FollowsWrapper.tsx +++ b/sample-apps/react-native/ExpoTikTokApp/components/follows/FollowsWrapper.tsx @@ -1,7 +1,8 @@ import { StreamFeed } from '@stream-io/feeds-react-native-sdk'; import { useLocalSearchParams } from 'expo-router'; import { useCreateAndQueryFeed } from '@/hooks/useCreateAndQueryFeed'; -import { PropsWithChildren, useMemo } from 'react'; +import type { PropsWithChildren} from 'react'; +import { useMemo } from 'react'; export const FollowsWrapper = ({ groupId, children }: PropsWithChildren<{ groupId: string }>) => { const { userId: userIdParam } = useLocalSearchParams(); diff --git a/sample-apps/react-native/ExpoTikTokApp/components/hashtags/HashtagFeedMetadata.tsx b/sample-apps/react-native/ExpoTikTokApp/components/hashtags/HashtagFeedMetadata.tsx index 3f05f7a6..02c9082d 100644 --- a/sample-apps/react-native/ExpoTikTokApp/components/hashtags/HashtagFeedMetadata.tsx +++ b/sample-apps/react-native/ExpoTikTokApp/components/hashtags/HashtagFeedMetadata.tsx @@ -1,7 +1,8 @@ -import React, { useMemo, useState, useCallback } from 'react'; -import { View, Text, Pressable, StyleSheet } from 'react-native'; -import { - FeedState, useFeedActivities, +import React from 'react'; +import { View, Text, StyleSheet } from 'react-native'; +import type { + FeedState} from '@stream-io/feeds-react-native-sdk'; +import { useFeedActivities, useFeedContext, useStateStore, } from '@stream-io/feeds-react-native-sdk'; diff --git a/sample-apps/react-native/ExpoTikTokApp/components/notifications/utils/getNotificationText.ts b/sample-apps/react-native/ExpoTikTokApp/components/notifications/utils/getNotificationText.ts index 4ebd3bfb..63faeae4 100644 --- a/sample-apps/react-native/ExpoTikTokApp/components/notifications/utils/getNotificationText.ts +++ b/sample-apps/react-native/ExpoTikTokApp/components/notifications/utils/getNotificationText.ts @@ -1,4 +1,4 @@ -import { AggregatedActivityResponse } from '@stream-io/feeds-react-native-sdk'; +import type { AggregatedActivityResponse } from '@stream-io/feeds-react-native-sdk'; export const getNotificationText = (aggregatedActivity: AggregatedActivityResponse) => { const { activities } = aggregatedActivity; diff --git a/sample-apps/react-native/ExpoTikTokApp/components/search/FeedSourceResultList.tsx b/sample-apps/react-native/ExpoTikTokApp/components/search/FeedSourceResultList.tsx index 33bd490f..0f4581da 100644 --- a/sample-apps/react-native/ExpoTikTokApp/components/search/FeedSourceResultList.tsx +++ b/sample-apps/react-native/ExpoTikTokApp/components/search/FeedSourceResultList.tsx @@ -1,5 +1,6 @@ +import type { + Feed} from '@stream-io/feeds-react-native-sdk'; import { - Feed, useClientConnectedUser, useFeedMetadata, useSearchResult, diff --git a/sample-apps/react-native/ExpoTikTokApp/components/search/SearchTabs.tsx b/sample-apps/react-native/ExpoTikTokApp/components/search/SearchTabs.tsx index e0d3843f..a93bcf0a 100644 --- a/sample-apps/react-native/ExpoTikTokApp/components/search/SearchTabs.tsx +++ b/sample-apps/react-native/ExpoTikTokApp/components/search/SearchTabs.tsx @@ -3,7 +3,6 @@ import { useEffect, useState } from 'react'; import { useSearchContext, useSearchSources, - SearchSource, } from '@stream-io/feeds-react-native-sdk'; const tabsNameMap = { diff --git a/sample-apps/react-native/ExpoTikTokApp/components/user-profile/FeedMetadata.tsx b/sample-apps/react-native/ExpoTikTokApp/components/user-profile/FeedMetadata.tsx index 396d62f7..406de8a0 100644 --- a/sample-apps/react-native/ExpoTikTokApp/components/user-profile/FeedMetadata.tsx +++ b/sample-apps/react-native/ExpoTikTokApp/components/user-profile/FeedMetadata.tsx @@ -1,9 +1,10 @@ import { Dimensions, Image, StyleSheet, TouchableOpacity } from 'react-native'; import { Text, View } from '@/components/common/Themed'; import React from 'react'; -import { +import type { Feed, - FeedState, + FeedState} from '@stream-io/feeds-react-native-sdk'; +import { useClientConnectedUser, useFeedMetadata, useStateStore, diff --git a/sample-apps/react-native/ExpoTikTokApp/contexts/OwnFeedsContext.tsx b/sample-apps/react-native/ExpoTikTokApp/contexts/OwnFeedsContext.tsx index 815e5dcc..adefd666 100644 --- a/sample-apps/react-native/ExpoTikTokApp/contexts/OwnFeedsContext.tsx +++ b/sample-apps/react-native/ExpoTikTokApp/contexts/OwnFeedsContext.tsx @@ -1,5 +1,6 @@ -import { createContext, PropsWithChildren, useContext, useMemo } from 'react'; -import { Feed } from '@stream-io/feeds-react-native-sdk'; +import type { PropsWithChildren} from 'react'; +import { createContext, useContext, useMemo } from 'react'; +import type { Feed } from '@stream-io/feeds-react-native-sdk'; import { useCreateAndQueryFeed } from '@/hooks/useCreateAndQueryFeed'; import { usePushNotifications } from '@/hooks/usePushNotifications'; diff --git a/sample-apps/react-native/ExpoTikTokApp/contexts/PostCreationContext.tsx b/sample-apps/react-native/ExpoTikTokApp/contexts/PostCreationContext.tsx index 0349eb7a..fda00787 100644 --- a/sample-apps/react-native/ExpoTikTokApp/contexts/PostCreationContext.tsx +++ b/sample-apps/react-native/ExpoTikTokApp/contexts/PostCreationContext.tsx @@ -1,11 +1,12 @@ +import type { + PropsWithChildren} from 'react'; import { createContext, - PropsWithChildren, useContext, useMemo, useState, } from 'react'; -import { Place } from '@/components/search/PlaceSearchDropdown'; +import type { Place } from '@/components/search/PlaceSearchDropdown'; import type { Attachment } from '@stream-io/feeds-react-native-sdk'; import { useActivityActionState } from '@/hooks/useActivityActionState'; diff --git a/sample-apps/react-native/ExpoTikTokApp/contexts/UserContext.tsx b/sample-apps/react-native/ExpoTikTokApp/contexts/UserContext.tsx index e7a02935..e6739caa 100644 --- a/sample-apps/react-native/ExpoTikTokApp/contexts/UserContext.tsx +++ b/sample-apps/react-native/ExpoTikTokApp/contexts/UserContext.tsx @@ -1,11 +1,12 @@ +import type { + PropsWithChildren} from 'react'; import { createContext, - PropsWithChildren, useContext, useEffect, useState, } from 'react'; -import { UserRequest } from '@stream-io/feeds-react-native-sdk'; +import type { UserRequest } from '@stream-io/feeds-react-native-sdk'; import AsyncStorage from '@react-native-async-storage/async-storage'; export type LocalUser = Pick & { token?: string }; diff --git a/sample-apps/react-native/ExpoTikTokApp/hooks/usePushNotifications.ts b/sample-apps/react-native/ExpoTikTokApp/hooks/usePushNotifications.ts index 42276a93..6496ecc3 100644 --- a/sample-apps/react-native/ExpoTikTokApp/hooks/usePushNotifications.ts +++ b/sample-apps/react-native/ExpoTikTokApp/hooks/usePushNotifications.ts @@ -1,3 +1,5 @@ +import type { + FirebaseMessagingTypes} from '@react-native-firebase/messaging'; import { getMessaging, getInitialNotification as fbGetInitialNotification, @@ -7,15 +9,15 @@ import { onNotificationOpenedApp, hasPermission, getToken, - AuthorizationStatus, - FirebaseMessagingTypes, + AuthorizationStatus } from '@react-native-firebase/messaging'; import { getApp } from '@react-native-firebase/app'; import notifee, { EventType } from '@notifee/react-native'; import { PermissionsAndroid, Platform } from 'react-native'; +import type { + CreateDeviceRequest} from '@stream-io/feeds-react-native-sdk'; import { - CreateDeviceRequest, useClientConnectedUser, useFeedsClient, } from '@stream-io/feeds-react-native-sdk'; diff --git a/sample-apps/react-native/ExpoTikTokApp/store/activity-action-state-store.ts b/sample-apps/react-native/ExpoTikTokApp/store/activity-action-state-store.ts index cd8ca9ef..7734984e 100644 --- a/sample-apps/react-native/ExpoTikTokApp/store/activity-action-state-store.ts +++ b/sample-apps/react-native/ExpoTikTokApp/store/activity-action-state-store.ts @@ -1,5 +1,6 @@ +import type { + ActivityResponse} from '@stream-io/feeds-react-native-sdk'; import { - ActivityResponse, StateStore, } from '@stream-io/feeds-react-native-sdk'; diff --git a/sample-apps/react-native/ExpoTikTokApp/store/bottom-sheet-state-store.ts b/sample-apps/react-native/ExpoTikTokApp/store/bottom-sheet-state-store.ts index a413c832..83b49c71 100644 --- a/sample-apps/react-native/ExpoTikTokApp/store/bottom-sheet-state-store.ts +++ b/sample-apps/react-native/ExpoTikTokApp/store/bottom-sheet-state-store.ts @@ -1,4 +1,5 @@ -import { CommentParent, StateStore } from '@stream-io/feeds-react-native-sdk'; +import type { CommentParent} from '@stream-io/feeds-react-native-sdk'; +import { StateStore } from '@stream-io/feeds-react-native-sdk'; export type BottomSheetData = | { diff --git a/sample-apps/react-native/ExpoTikTokApp/store/comment-input-state-store.ts b/sample-apps/react-native/ExpoTikTokApp/store/comment-input-state-store.ts index bfb9ec59..667908ab 100644 --- a/sample-apps/react-native/ExpoTikTokApp/store/comment-input-state-store.ts +++ b/sample-apps/react-native/ExpoTikTokApp/store/comment-input-state-store.ts @@ -1,4 +1,5 @@ -import { CommentParent, StateStore } from '@stream-io/feeds-react-native-sdk'; +import type { CommentParent} from '@stream-io/feeds-react-native-sdk'; +import { StateStore } from '@stream-io/feeds-react-native-sdk'; export type CommentInputState = { editingEntity?: CommentParent; diff --git a/sample-apps/react-native/ExpoTikTokApp/utils/push-notifications/extractNotificationConfig.ts b/sample-apps/react-native/ExpoTikTokApp/utils/push-notifications/extractNotificationConfig.ts index b04bb10c..49e69643 100644 --- a/sample-apps/react-native/ExpoTikTokApp/utils/push-notifications/extractNotificationConfig.ts +++ b/sample-apps/react-native/ExpoTikTokApp/utils/push-notifications/extractNotificationConfig.ts @@ -1,4 +1,4 @@ -import { FirebaseMessagingTypes } from '@react-native-firebase/messaging'; +import type { FirebaseMessagingTypes } from '@react-native-firebase/messaging'; export const extractNotificationConfig = ( remoteMessage: FirebaseMessagingTypes.RemoteMessage, diff --git a/sample-apps/react-native/ExpoTikTokApp/utils/push-notifications/navigateFromData.ts b/sample-apps/react-native/ExpoTikTokApp/utils/push-notifications/navigateFromData.ts index 28651abc..3d69117c 100644 --- a/sample-apps/react-native/ExpoTikTokApp/utils/push-notifications/navigateFromData.ts +++ b/sample-apps/react-native/ExpoTikTokApp/utils/push-notifications/navigateFromData.ts @@ -1,5 +1,5 @@ import { router } from 'expo-router'; -import { MessagingDataType } from '@/hooks/usePushNotifications'; +import type { MessagingDataType } from '@/hooks/usePushNotifications'; export const navigateFromData = (data?: MessagingDataType) => { if (!data) { diff --git a/sample-apps/react-sample-app/app/activity/[id]/page.tsx b/sample-apps/react-sample-app/app/activity/[id]/page.tsx index 8f9dfe51..70b35664 100644 --- a/sample-apps/react-sample-app/app/activity/[id]/page.tsx +++ b/sample-apps/react-sample-app/app/activity/[id]/page.tsx @@ -1,13 +1,16 @@ 'use client'; -import { useCallback, useEffect, useMemo, useState } from 'react'; -import { useUserContext } from '@/app/user-context'; +import { useCallback, useEffect, useState } from 'react'; import { LoadingIndicator } from '@/app/components/LoadingIndicator'; import { useParams } from 'next/navigation'; import { useErrorContext } from '@/app/error-context'; -import { +import type { ActivityWithStateUpdates, Feed, +} from '@stream-io/feeds-react-sdk'; +import { FeedOwnCapability, + useFeedsClient, + useOwnCapabilities, useStateStore, type ActivityState, } from '@stream-io/feeds-react-sdk'; @@ -17,7 +20,6 @@ import { ActivityMetadata } from '@/app/components/activity/ActivityMetadata'; import { ActivityActions } from '@/app/components/activity/ActivityActions'; import { ActivityContent } from '@/app/components/activity/ActivityContent'; import { ActivityCommentSection } from '@/app/components/comments/ActivityCommentSection'; -import { useOwnCapabilities } from '@/app/hooks/useOwnCapabilities'; // I need the isMounted to prevent this error from Next: // "Missing getServerSnapshot, which is required for server-rendered content. Will revert to client rendering." @@ -38,7 +40,7 @@ export default function ActivityPage() { function ActivityPageContent() { const params = useParams<{ id: string }>(); - const { client } = useUserContext(); + const client = useFeedsClient(); const { logErrorAndDisplayNotification, logError } = useErrorContext(); const [editedActivityText, setEditedActivityText] = useState(''); const [isEditing, setIsEditing] = useState(false); @@ -53,10 +55,13 @@ function ActivityPageContent() { return; } - setActivityWithStateUpdates(client.activityWithStateUpdates(params.id)); + const _activityWithStateUpdates = client.activityWithStateUpdates( + params.id, + ); + setActivityWithStateUpdates(_activityWithStateUpdates); return () => { - activityWithStateUpdates?.dispose(); + _activityWithStateUpdates?.dispose(); }; }, [client, params?.id]); @@ -66,16 +71,17 @@ function ActivityPageContent() { } let shouldStopWatching: boolean = false; + let _feed: Feed | undefined; activityWithStateUpdates .get() .then((response) => { const fid = response.feeds[0]; const [group, id] = fid.split(':'); - const feed = client?.feed(group, id); - setFeed(feed); - if (!feed?.currentState.watch && !feed?.currentState.is_loading) { + _feed = client?.feed(group, id); + setFeed(_feed); + if (!_feed?.currentState.watch && !_feed?.currentState.is_loading) { shouldStopWatching = true; - return feed + return _feed ?.getOrCreate({ watch: true, limit: 0, @@ -89,12 +95,17 @@ function ActivityPageContent() { return () => { if (shouldStopWatching) { - feed?.stopWatching(); + _feed?.stopWatching(); } }; - }, [logErrorAndDisplayNotification, activityWithStateUpdates, client]); - - const ownCapabilities = useOwnCapabilities({ feed }); + }, [ + logErrorAndDisplayNotification, + logError, + activityWithStateUpdates, + client, + ]); + + const ownCapabilities = useOwnCapabilities(feed); const activitySelector = useCallback((state: ActivityState) => { return { diff --git a/sample-apps/react-sample-app/app/api/create-token/route.ts b/sample-apps/react-sample-app/app/api/create-token/route.ts index c80ba652..312b6176 100644 --- a/sample-apps/react-sample-app/app/api/create-token/route.ts +++ b/sample-apps/react-sample-app/app/api/create-token/route.ts @@ -1,10 +1,7 @@ import { streamServerClient } from '../client'; import { cookies } from 'next/headers'; -export async function GET( - req: Request, - ctx: { params?: Record } = {}, -) { +export async function GET(req: Request) { const cookieId = (await cookies()).get('user_id')?.value; // 1) query string: ?user_id=... or ?userId=... @@ -12,10 +9,7 @@ export async function GET( const queryUserId = url.searchParams.get('user_id') ?? url.searchParams.get('userId'); - // 2) dynamic route param: /api/token/[userId] - const routeUserId = ctx.params?.userId; - - const userId = cookieId ?? queryUserId ?? routeUserId; + const userId = cookieId ?? queryUserId; if (!userId) { return new Response(JSON.stringify({ error: 'missing_user_id' }), { diff --git a/sample-apps/react-sample-app/app/api/send-notification/route.ts b/sample-apps/react-sample-app/app/api/send-notification/route.ts deleted file mode 100644 index 09274071..00000000 --- a/sample-apps/react-sample-app/app/api/send-notification/route.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { cookies } from 'next/headers'; -import { streamServerClient } from '../client'; - -export async function POST(request: Request) { - const body = await request.json(); - const verb = body.verb; - const objectId = body.objectId; - const targetUserId = body.targetUserId; - const userId = (await cookies()).get('user_id')?.value; - - if (!verb || !targetUserId || !objectId) { - return new Response(undefined, { - status: 401, - }); - } - - if (targetUserId === userId) { - return new Response(undefined, { - status: 201, - }); - } - - try { - // TODO: Migrate to new API - // await streamServerClient().feeds - // .feed('notification', targetUserId) - // .addActivity({ - // verb, - // object: objectId, - // user_id: userId, - // }); - } catch (err) { - return new Response(undefined, { - status: 500, - }); - } - - return new Response(undefined, { - status: 201, - }); -} diff --git a/sample-apps/react-sample-app/app/app-notifications-context.tsx b/sample-apps/react-sample-app/app/app-notifications-context.tsx index 44eb68b5..12a36616 100644 --- a/sample-apps/react-sample-app/app/app-notifications-context.tsx +++ b/sample-apps/react-sample-app/app/app-notifications-context.tsx @@ -1,7 +1,8 @@ 'use client'; +import type { + PropsWithChildren} from 'react'; import { createContext, - PropsWithChildren, useCallback, useContext, useRef, diff --git a/sample-apps/react-sample-app/app/components/AppNotifications.tsx b/sample-apps/react-sample-app/app/components/AppNotifications.tsx index a977280a..cb8626b5 100644 --- a/sample-apps/react-sample-app/app/components/AppNotifications.tsx +++ b/sample-apps/react-sample-app/app/components/AppNotifications.tsx @@ -1,12 +1,13 @@ 'use client'; import React from 'react'; +import type { + AppNotificationType} from '../app-notifications-context'; import { - AppNotificationType, useAppNotificationsContext, } from '../app-notifications-context'; const AppNotifications = () => { - const backgroundColors: { [key in AppNotificationType]: string } = { + const backgroundColors: Record = { info: 'bg-blue-500', success: 'bg-green-500', warning: 'bg-yellow-500', diff --git a/sample-apps/react-sample-app/app/components/Dialog.tsx b/sample-apps/react-sample-app/app/components/Dialog.tsx index 269912ef..094bd542 100644 --- a/sample-apps/react-sample-app/app/components/Dialog.tsx +++ b/sample-apps/react-sample-app/app/components/Dialog.tsx @@ -1,6 +1,7 @@ -import { +import type { ReactNode, - Ref, + Ref} from 'react'; +import { useEffect, useImperativeHandle, useState, diff --git a/sample-apps/react-sample-app/app/components/Feed.tsx b/sample-apps/react-sample-app/app/components/Feed.tsx index f2767aca..6db3de8c 100644 --- a/sample-apps/react-sample-app/app/components/Feed.tsx +++ b/sample-apps/react-sample-app/app/components/Feed.tsx @@ -1,40 +1,42 @@ +import type { + ActivityResponse} from '@stream-io/feeds-react-sdk'; import { - ActivityResponse, - Feed as StreamFeed, + useFeedContext, + useOwnCapabilities, } from '@stream-io/feeds-react-sdk'; import { useState } from 'react'; import { Activity } from './activity/Activity'; import { PaginatedList } from './PaginatedList'; import { useStateStore } from '@stream-io/feeds-react-sdk'; -import { useOwnCapabilities } from '../hooks/useOwnCapabilities'; -export const Feed = ({ feed }: { feed: StreamFeed }) => { +export const Feed = () => { const [error, setError] = useState(); + const feed = useFeedContext(); const { hasNextPage, isLoading, activities } = useStateStore( - feed.state, + feed?.state, (state) => ({ isLoading: state.is_loading_activities, hasNextPage: typeof state.next !== 'undefined', activities: state.activities ?? [], }), - ); + ) ?? { + hasNextPage: false, + isLoading: false, + activities: [], + }; - const ownCapabilities = useOwnCapabilities({ feed }); + const ownCapabilities = useOwnCapabilities(); const getNextPage = () => { setError(undefined); - feed.getNextPage().catch(setError); + feed?.getNextPage().catch(setError); }; const renderItem = (activity: ActivityResponse) => { return (
  • - +
  • ); }; diff --git a/sample-apps/react-sample-app/app/components/FeedList.tsx b/sample-apps/react-sample-app/app/components/FeedList.tsx deleted file mode 100644 index 0c5785c5..00000000 --- a/sample-apps/react-sample-app/app/components/FeedList.tsx +++ /dev/null @@ -1,110 +0,0 @@ -'use client'; -import { useCallback, useEffect, useState } from 'react'; -import type { Feed, FeedState } from '@stream-io/feeds-react-sdk'; -import { useStateStore } from '@stream-io/feeds-react-sdk'; -import Link from 'next/link'; - -import { useUserContext } from '../user-context'; -import { useFeedContext } from '../feed-context'; -import { PaginatedList } from '../components/PaginatedList'; -import { FollowStatusButton } from './FollowStatusButton'; - -const selector = (state: FeedState) => { - return { - createdBy: state.created_by, - }; -}; - -const UserItem = ({ feed }: { feed: Feed }) => { - const { createdBy } = useStateStore(feed.state, selector); - - return ( -
  • - -
    - -

    - {createdBy?.name ?? feed.feed} -

    -
    - - -
  • - ); -}; - -export default function FeedList({ types }: { types: Array<'user'> }) { - const { client, user } = useUserContext(); - const [isLoading, setIsLoading] = useState(false); - const [error, setError] = useState(); - const [next, setNext] = useState(undefined); - const [feeds, setFeeds] = useState([]); - const { ownTimeline } = useFeedContext(); - - const [title, setTitle] = useState(''); - - useEffect(() => { - if (types.length > 1) { - setTitle('Feeds'); - } else if (types.length === 1) { - switch (types[0]) { - case 'user': - setTitle('Users'); - break; - } - } - }, [types]); - - const loadMore = useCallback(async () => { - if (!client || !user || !ownTimeline) { - return; - } - setError(undefined); - setIsLoading(true); - const limit = 30; - try { - const response = await client.queryFeeds({ - limit, - filter: { - group_id: { $in: types }, - }, - next, - }); - const newFeeds = response.feeds.filter((f) => f.id !== user.id); - setFeeds([...feeds, ...newFeeds]); - setNext(response.next); - } catch (e) { - setError(e as Error); - } finally { - setIsLoading(false); - } - }, [client, feeds, next, ownTimeline, types, user]); - - useEffect(() => { - if (!client || !user || !ownTimeline) { - return; - } - void loadMore(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [client, user, ownTimeline]); - - const renderUser = (feed: Feed) => { - return ; - }; - - return ( -
    -

    {title}

    - -
    - ); -} diff --git a/sample-apps/react-sample-app/app/components/FeedMenu.tsx b/sample-apps/react-sample-app/app/components/FeedMenu.tsx index 72a388ed..72ac2e3a 100644 --- a/sample-apps/react-sample-app/app/components/FeedMenu.tsx +++ b/sample-apps/react-sample-app/app/components/FeedMenu.tsx @@ -1,16 +1,11 @@ -import type { Feed } from '@stream-io/feeds-react-sdk'; import { useState } from 'react'; -import { useUserContext } from '../user-context'; type Action = 'null'; -export const FeedMenu = ({ feed }: { feed: Feed }) => { - const { user } = useUserContext(); +export const FeedMenu = () => { const [isMenuOpen, setIsMenuOpen] = useState(false); - const [enabledActions, setEnabledActions] = useState([]); - const actionMapping: { - [key in Action]: { label: string; icon: string; handler: () => void }; - } = { + const [enabledActions] = useState([]); + const actionMapping: Record void }> = { null: { label: '', icon: '', diff --git a/sample-apps/react-sample-app/app/components/FeedMetadata.tsx b/sample-apps/react-sample-app/app/components/FeedMetadata.tsx index 4e6039dc..b1b09b12 100644 --- a/sample-apps/react-sample-app/app/components/FeedMetadata.tsx +++ b/sample-apps/react-sample-app/app/components/FeedMetadata.tsx @@ -1,6 +1,9 @@ import type { FeedState, Feed } from '@stream-io/feeds-react-sdk'; -import { FeedOwnCapability } from '@stream-io/feeds-react-sdk'; -import { useRef, useState } from 'react'; +import { + FeedOwnCapability, + useOwnCapabilities, +} from '@stream-io/feeds-react-sdk'; +import { useMemo, useRef, useState } from 'react'; import { LoadingIndicator } from './LoadingIndicator'; import { FollowRelationships } from './FollowRelationships'; import { FollowStatusButton } from './FollowStatusButton'; @@ -9,7 +12,6 @@ import { useStateStore } from '@stream-io/feeds-react-sdk'; import { Dialog } from './Dialog'; const selector = ({ - own_capabilities = [], follower_count = 0, following_count = 0, created_by, @@ -21,8 +23,6 @@ const selector = ({ createdBy: created_by, followerCount: follower_count - 1, followingCount: following_count - 1, - canReadFeed: own_capabilities.includes(FeedOwnCapability.READ_FEED), - canQueryFollows: own_capabilities.includes(FeedOwnCapability.QUERY_FOLLOWS), followStatus: f?.status, }; }; @@ -45,8 +45,12 @@ export const FeedMetadata = ({ const followerCount = userFeedState.followerCount; const followingCount = timelineFeedState?.followingCount; - const canQueryFollowers = userFeedState.canQueryFollows; - const canQueryFollowings = timelineFeedState?.canQueryFollows; + const ownCapabilities = useOwnCapabilities(userFeed); + + const canQueryFollows = useMemo( + () => ownCapabilities.includes(FeedOwnCapability.QUERY_FOLLOWS), + [ownCapabilities], + ); const openDialog = () => { dialogRef.current?.showModal(); @@ -75,8 +79,8 @@ export const FeedMetadata = ({ )} diff --git a/sample-apps/react-tutorial/src/pages/SearchResults.tsx b/sample-apps/react-tutorial/src/pages/SearchResults.tsx index d5fc9f85..79d9c385 100644 --- a/sample-apps/react-tutorial/src/pages/SearchResults.tsx +++ b/sample-apps/react-tutorial/src/pages/SearchResults.tsx @@ -1,7 +1,8 @@ -import { - useFeedsClient, +import type { ActivityResponse, - Feed, + Feed} from '@stream-io/feeds-react-sdk'; +import { + useFeedsClient } from '@stream-io/feeds-react-sdk'; import { useState, useCallback, useEffect } from 'react'; import { ActivitySearchResult } from '../components/activity/ActivitySearchResult';