diff --git a/ios/patching/008-social-app-ios-policy-tos-error.patch b/ios/patching/008-social-app-ios-policy-tos-error.patch index 83015ec..fd7d591 100644 --- a/ios/patching/008-social-app-ios-policy-tos-error.patch +++ b/ios/patching/008-social-app-ios-policy-tos-error.patch @@ -1,8 +1,8 @@ diff --git a/src/view/screens/PrivacyPolicy.tsx b/src/view/screens/PrivacyPolicy.tsx -index a89eaadc4..1da393f03 100644 +index a89eaadc4..045f660ef 100644 --- a/src/view/screens/PrivacyPolicy.tsx +++ b/src/view/screens/PrivacyPolicy.tsx -@@ -1,52 +1,13 @@ +@@ -1,51 +1,28 @@ import React from 'react' -import {View} from 'react-native' -import {msg, Trans} from '@lingui/macro' @@ -19,7 +19,7 @@ index a89eaadc4..1da393f03 100644 -import {TextLink} from '#/view/com/util/Link' -import {Text} from '#/view/com/util/text/Text' -import {ScrollView} from '#/view/com/util/Views' -+import { WebView } from 'react-native-webview' ++import {ScrollView} from 'react-native' import * as Layout from '#/components/Layout' -import {ViewHeader} from '../com/util/ViewHeader' - @@ -28,16 +28,19 @@ index a89eaadc4..1da393f03 100644 - const pal = usePalette('default') - const {_} = useLingui() - const setMinimalShellMode = useSetMinimalShellMode() -- ++import {useSetTitle} from '#/lib/hooks/useSetTitle' ++import {atoms as a, useTheme} from '#/alf' ++import {Text} from '#/components/Typography' + - useFocusEffect( - React.useCallback(() => { - setMinimalShellMode(false) - }, [setMinimalShellMode]), - ) -+import {useSetTitle} from '#/lib/hooks/useSetTitle' - +export function PrivacyPolicyScreen() { + useSetTitle('Privacy Policy') ++ const t = useTheme() + return ( - @@ -55,16 +58,26 @@ index a89eaadc4..1da393f03 100644 - - - -- -+ ++ ++ Privacy Policy ++ ++ ++ Please refer to the following page for the Privacy Policy. ++ ++ ++ ++ https://syu.is/about/support/privacy-policy ++ + ) - } diff --git a/src/view/screens/TermsOfService.tsx b/src/view/screens/TermsOfService.tsx -index d843c713c..b81767bd5 100644 +index d843c713c..324b270af 100644 --- a/src/view/screens/TermsOfService.tsx +++ b/src/view/screens/TermsOfService.tsx -@@ -1,50 +1,13 @@ +@@ -1,49 +1,28 @@ import React from 'react' -import {View} from 'react-native' -import {msg, Trans} from '@lingui/macro' @@ -81,7 +94,7 @@ index d843c713c..b81767bd5 100644 -import {TextLink} from '#/view/com/util/Link' -import {Text} from '#/view/com/util/text/Text' -import {ScrollView} from '#/view/com/util/Views' -+import { WebView } from 'react-native-webview' ++import {ScrollView} from 'react-native' import * as Layout from '#/components/Layout' -import {ViewHeader} from '../com/util/ViewHeader' - @@ -90,16 +103,19 @@ index d843c713c..b81767bd5 100644 - const pal = usePalette('default') - const setMinimalShellMode = useSetMinimalShellMode() - const {_} = useLingui() -- ++import {useSetTitle} from '#/lib/hooks/useSetTitle' ++import {atoms as a, useTheme} from '#/alf' ++import {Text} from '#/components/Typography' + - useFocusEffect( - React.useCallback(() => { - setMinimalShellMode(false) - }, [setMinimalShellMode]), - ) -+import {useSetTitle} from '#/lib/hooks/useSetTitle' - +export function TermsOfServiceScreen() { + useSetTitle('Terms of Service') ++ const t = useTheme() + return ( - @@ -115,8 +131,18 @@ index d843c713c..b81767bd5 100644 - - - -- -+ ++ ++ Terms of Service ++ ++ ++ Please refer to the following page for the Terms of Service. ++ ++ ++ ++ https://syu.is/about/support/tos ++ + ) - } diff --git a/ios/patching/009-social-app-ios-license.patch b/ios/patching/009-social-app-ios-license.patch index 0d94461..70b7509 100644 --- a/ios/patching/009-social-app-ios-license.patch +++ b/ios/patching/009-social-app-ios-license.patch @@ -34,15 +34,719 @@ index c315a8341..9b2f50a83 100644 CommunityGuidelines: undefined CopyrightPolicy: undefined LanguageSettings: undefined +diff --git a/src/view/screens/License.tsx b/src/view/screens/License.tsx +new file mode 100644 +index 000000000..f98cd6afc +--- /dev/null ++++ b/src/view/screens/License.tsx +@@ -0,0 +1,86 @@ ++import React from 'react' ++import { ScrollView } from 'react-native' ++import * as Layout from '#/components/Layout' ++import {useSetTitle} from '#/lib/hooks/useSetTitle' ++import {atoms as a, useTheme} from '#/alf' ++import {Text} from '#/components/Typography' ++ ++export function LicenseScreen() { ++ useSetTitle('License') ++ const t = useTheme() ++ ++ return ( ++ ++ ++ License ++ ++ ++ This application is based on Bluesky Social App. ++ ++ ++ ++ https://github.com/bluesky-social/social-app ++ ++ ++ MIT License ++ ++ ++ Copyright (c) 2022-2025 Bluesky PBC ++ ++ ++ ++ Permission is hereby granted, free of charge, to any person obtaining a copy ++ of this software and associated documentation files (the "Software"), to deal ++ in the Software without restriction, including without limitation the rights ++ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++ copies of the Software, and to permit persons to whom the Software is ++ furnished to do so, subject to the following conditions: ++ ++ ++ ++ The above copyright notice and this permission notice shall be included in all ++ copies or substantial portions of the Software. ++ ++ ++ ++ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE ++ SOFTWARE. ++ ++ ++ 日本語訳(参考) ++ ++ ++ 本ソフトウェアおよび関連文書ファイル(以下「ソフトウェア」)のコピーを取得する ++ すべての人に対し、ソフトウェアを無制限に扱うことを無償で許可します。これには、 ++ ソフトウェアのコピーを使用、複製、変更、結合、公開、配布、サブライセンス、 ++ および/または販売する権利、ならびにソフトウェアを提供する相手にそうした行為を ++ 許可する権利が含まれますが、これらに限定されません。 ++ ++ ++ ++ 上記の著作権表示および本許諾表示を、ソフトウェアのすべてのコピーまたは ++ 重要な部分に記載するものとします。 ++ ++ ++ ++ ソフトウェアは「現状のまま」で提供され、明示黙示を問わず、商品性、特定目的への ++ 適合性、および権利非侵害についての保証を含む、いかなる種類の保証もなされません。 ++ いかなる場合においても、作者または著作権者は、契約行為、不法行為、またはそれ以外で ++ あろうと、ソフトウェアに起因または関連し、あるいはソフトウェアの使用または ++ その他の扱いによって生じる一切の請求、損害、その他の義務について責任を負わないものとします。 ++ ++ ++ ++ Original License: https://github.com/bluesky-social/social-app/blob/main/LICENSE ++ ++ ++ ++ ) ++} diff --git a/src/view/shell/Drawer.tsx b/src/view/shell/Drawer.tsx -index ed2a6cfb7..0b429e6f3 100644 +index ed2a6cfb7..982c40b55 100644 --- a/src/view/shell/Drawer.tsx +++ b/src/view/shell/Drawer.tsx -@@ -460,6 +460,11 @@ function ExtraLinks() { - - Privacy Policy +@@ -1,60 +1,50 @@ +-import React, {type ComponentProps, type JSX} from 'react' +-import {Linking, ScrollView, TouchableOpacity, View} from 'react-native' +-import {useSafeAreaInsets} from 'react-native-safe-area-context' +-import {msg, Plural, plural, Trans} from '@lingui/macro' +-import {useLingui} from '@lingui/react' +-import {StackActions, useNavigation} from '@react-navigation/native' +- +-import {useActorStatus} from '#/lib/actor-status' +-import {FEEDBACK_FORM_URL, HELP_DESK_URL} from '#/lib/constants' +-import {type PressableScale} from '#/lib/custom-animations/PressableScale' +-import {useNavigationTabState} from '#/lib/hooks/useNavigationTabState' +-import {getTabState, TabState} from '#/lib/routes/helpers' +-import {type NavigationProp} from '#/lib/routes/types' +-import {sanitizeHandle} from '#/lib/strings/handles' +-import {colors} from '#/lib/styles' +-import {isWeb} from '#/platform/detection' +-import {emitSoftReset} from '#/state/events' +-import {useKawaiiMode} from '#/state/preferences/kawaii' +-import {useUnreadNotifications} from '#/state/queries/notifications/unread' +-import {useProfileQuery} from '#/state/queries/profile' +-import {type SessionAccount, useSession} from '#/state/session' +-import {useSetDrawerOpen} from '#/state/shell' +-import {formatCount} from '#/view/com/util/numeric/format' +-import {UserAvatar} from '#/view/com/util/UserAvatar' +-import {NavSignupCard} from '#/view/shell/NavSignupCard' +-import {atoms as a, tokens, useTheme, web} from '#/alf' +-import {Button, ButtonIcon, ButtonText} from '#/components/Button' +-import {Divider} from '#/components/Divider' ++import React, { type ComponentProps, type JSX } from 'react' ++import { Linking, ScrollView, TouchableOpacity, View } from 'react-native' ++import { useSafeAreaInsets } from 'react-native-safe-area-context' ++import { msg, Plural, plural, Trans } from '@lingui/macro' ++import { useLingui } from '@lingui/react' ++import { StackActions, useNavigation } from '@react-navigation/native' ++ ++import { useActorStatus } from '#/lib/actor-status' ++import { FEEDBACK_FORM_URL, HELP_DESK_URL } from '#/lib/constants' ++import { type PressableScale } from '#/lib/custom-animations/PressableScale' ++import { useNavigationTabState } from '#/lib/hooks/useNavigationTabState' ++import { getTabState, TabState } from '#/lib/routes/helpers' ++import { type NavigationProp } from '#/lib/routes/types' ++import { sanitizeHandle } from '#/lib/strings/handles' ++import { colors } from '#/lib/styles' ++import { isWeb } from '#/platform/detection' ++import { emitSoftReset } from '#/state/events' ++import { useKawaiiMode } from '#/state/preferences/kawaii' ++import { useUnreadNotifications } from '#/state/queries/notifications/unread' ++import { useProfileQuery } from '#/state/queries/profile' ++import { type SessionAccount, useSession } from '#/state/session' ++import { useSetDrawerOpen } from '#/state/shell' ++import { formatCount } from '#/view/com/util/numeric/format' ++import { UserAvatar } from '#/view/com/util/UserAvatar' ++import { NavSignupCard } from '#/view/shell/NavSignupCard' ++import { atoms as a, tokens, useTheme, web } from '#/alf' ++import { Button } from '#/components/Button' ++import { Divider } from '#/components/Divider' + import { + Bell_Filled_Corner0_Rounded as BellFilled, + Bell_Stroke2_Corner0_Rounded as Bell, + } from '#/components/icons/Bell' +-import {Bookmark, BookmarkFilled} from '#/components/icons/Bookmark' +-import {BulletList_Stroke2_Corner0_Rounded as List} from '#/components/icons/BulletList' +-import { +- Hashtag_Filled_Corner0_Rounded as HashtagFilled, +- Hashtag_Stroke2_Corner0_Rounded as Hashtag, +-} from '#/components/icons/Hashtag' + import { + HomeOpen_Filled_Corner0_Rounded as HomeFilled, + HomeOpen_Stoke2_Corner0_Rounded as Home, + } from '#/components/icons/HomeOpen' +-import {MagnifyingGlass_Filled_Stroke2_Corner0_Rounded as MagnifyingGlassFilled} from '#/components/icons/MagnifyingGlass' +-import {MagnifyingGlass2_Stroke2_Corner0_Rounded as MagnifyingGlass} from '#/components/icons/MagnifyingGlass2' +-import { +- Message_Stroke2_Corner0_Rounded as Message, +- Message_Stroke2_Corner0_Rounded_Filled as MessageFilled, +-} from '#/components/icons/Message' +-import {SettingsGear2_Stroke2_Corner0_Rounded as Settings} from '#/components/icons/SettingsGear2' ++import { MagnifyingGlass_Filled_Stroke2_Corner0_Rounded as MagnifyingGlassFilled } from '#/components/icons/MagnifyingGlass' ++import { MagnifyingGlass2_Stroke2_Corner0_Rounded as MagnifyingGlass } from '#/components/icons/MagnifyingGlass2' ++import { SettingsGear2_Stroke2_Corner0_Rounded as Settings } from '#/components/icons/SettingsGear2' + import { + UserCircle_Filled_Corner0_Rounded as UserCircleFilled, + UserCircle_Stroke2_Corner0_Rounded as UserCircle, + } from '#/components/icons/UserCircle' +-import {InlineLinkText} from '#/components/Link' +-import {Text} from '#/components/Typography' +-import {useSimpleVerificationState} from '#/components/verification' +-import {VerificationCheck} from '#/components/verification/VerificationCheck' ++import { InlineLinkText } from '#/components/Link' ++import { Text } from '#/components/Typography' ++import { useSimpleVerificationState } from '#/components/verification' ++import { VerificationCheck } from '#/components/verification/VerificationCheck' + + const iconWidth = 26 + +@@ -65,11 +55,11 @@ let DrawerProfileCard = ({ + account: SessionAccount + onPressProfile: () => void + }): React.ReactNode => { +- const {_, i18n} = useLingui() ++ const { _, i18n } = useLingui() + const t = useTheme() +- const {data: profile} = useProfileQuery({did: account.did}) +- const verification = useSimpleVerificationState({profile}) +- const {isActive: live} = useActorStatus(profile) ++ const { data: profile } = useProfileQuery({ did: account.did }) ++ const verification = useSimpleVerificationState({ profile }) ++ const { isActive: live } = useActorStatus(profile) + + return ( + ): React.ReactNode => { ++let DrawerContent = ({ }: React.PropsWithoutRef<{}>): React.ReactNode => { + const t = useTheme() + const insets = useSafeAreaInsets() + const setDrawerOpen = useSetDrawerOpen() +@@ -150,27 +139,20 @@ let DrawerContent = ({}: React.PropsWithoutRef<{}>): React.ReactNode => { + const { + isAtHome, + isAtSearch, +- isAtFeeds, +- isAtBookmarks, + isAtNotifications, + isAtMyProfile, +- isAtMessages, + } = useNavigationTabState() +- const {hasSession, currentAccount} = useSession() +- +- // events +- // = ++ const { hasSession, currentAccount } = useSession() + + const onPressTab = React.useCallback( + (tab: 'Home' | 'Search' | 'Messages' | 'Notifications' | 'MyProfile') => { + const state = navigation.getState() + setDrawerOpen(false) + if (isWeb) { +- // hack because we have flat navigator for web and MyProfile does not exist on the web navigator -ansh + if (tab === 'MyProfile') { +- navigation.navigate('Profile', {name: currentAccount!.handle}) ++ navigation.navigate('Profile', { name: currentAccount!.handle }) + } else { +- // @ts-expect-error struggles with string unions, apparently ++ // @ts-expect-error struggles with string unions + navigation.navigate(tab) + } + } else { +@@ -178,21 +160,11 @@ let DrawerContent = ({}: React.PropsWithoutRef<{}>): React.ReactNode => { + if (tabState === TabState.InsideAtRoot) { + emitSoftReset() + } else if (tabState === TabState.Inside) { +- // find the correct navigator in which to pop-to-top +- const target = state.routes.find(route => route.name === `${tab}Tab`) +- ?.state?.key ++ const target = state.routes.find(route => route.name === `${tab}Tab`)?.state?.key + if (target) { +- // if we found it, trigger pop-to-top +- navigation.dispatch({ +- ...StackActions.popToTop(), +- target, +- }) ++ navigation.dispatch({ ...StackActions.popToTop(), target }) + } else { +- // fallback: reset navigation +- navigation.reset({ +- index: 0, +- routes: [{name: `${tab}Tab`}], +- }) ++ navigation.reset({ index: 0, routes: [{ name: `${tab}Tab` }] }) + } + } else { + navigation.navigate(`${tab}Tab`) +@@ -203,76 +175,21 @@ let DrawerContent = ({}: React.PropsWithoutRef<{}>): React.ReactNode => { + ) + + const onPressHome = React.useCallback(() => onPressTab('Home'), [onPressTab]) +- +- const onPressSearch = React.useCallback( +- () => onPressTab('Search'), +- [onPressTab], +- ) +- +- const onPressMessages = React.useCallback( +- () => onPressTab('Messages'), +- [onPressTab], +- ) +- +- const onPressNotifications = React.useCallback( +- () => onPressTab('Notifications'), +- [onPressTab], +- ) +- +- const onPressProfile = React.useCallback(() => { +- onPressTab('MyProfile') +- }, [onPressTab]) +- +- const onPressMyFeeds = React.useCallback(() => { +- navigation.navigate('Feeds') +- setDrawerOpen(false) +- }, [navigation, setDrawerOpen]) +- +- const onPressLists = React.useCallback(() => { +- navigation.navigate('Lists') +- setDrawerOpen(false) +- }, [navigation, setDrawerOpen]) +- +- const onPressBookmarks = React.useCallback(() => { +- navigation.navigate('Bookmarks') +- setDrawerOpen(false) +- }, [navigation, setDrawerOpen]) +- ++ const onPressSearch = React.useCallback(() => onPressTab('Search'), [onPressTab]) ++ const onPressNotifications = React.useCallback(() => onPressTab('Notifications'), [onPressTab]) ++ const onPressProfile = React.useCallback(() => { onPressTab('MyProfile') }, [onPressTab]) + const onPressSettings = React.useCallback(() => { + navigation.navigate('Settings') + setDrawerOpen(false) + }, [navigation, setDrawerOpen]) + +- const onPressFeedback = React.useCallback(() => { +- Linking.openURL( +- FEEDBACK_FORM_URL({ +- email: currentAccount?.email, +- handle: currentAccount?.handle, +- }), +- ) +- }, [currentAccount]) +- +- const onPressHelp = React.useCallback(() => { +- Linking.openURL(HELP_DESK_URL) +- }, []) +- +- // rendering +- // = +- + return ( + + ++ contentContainerStyle={[{ paddingTop: Math.max(insets.top + a.pt_xl.paddingTop, a.pt_xl.paddingTop) }]}> + + {hasSession && currentAccount ? ( + ): React.ReactNode => { + + + )} +- + + + +@@ -292,17 +208,10 @@ let DrawerContent = ({}: React.PropsWithoutRef<{}>): React.ReactNode => { + <> + + +- + +- +- +- + ): React.ReactNode => { + ) : ( + <> + +- + + + )} +@@ -322,69 +230,11 @@ let DrawerContent = ({}: React.PropsWithoutRef<{}>): React.ReactNode => { + + + +- +- + + ) + } + DrawerContent = React.memo(DrawerContent) +-export {DrawerContent} +- +-let DrawerFooter = ({ +- onPressFeedback, +- onPressHelp, +-}: { +- onPressFeedback: () => void +- onPressHelp: () => void +-}): React.ReactNode => { +- const {_} = useLingui() +- const insets = useSafeAreaInsets() +- return ( +- +- +- +- +- ) +-} +-DrawerFooter = React.memo(DrawerFooter) ++export { DrawerContent } + + interface MenuItemProps extends ComponentProps { + icon: JSX.Element +@@ -400,7 +250,7 @@ let SearchMenuItem = ({ + isActive: boolean + onPress: () => void + }): React.ReactNode => { +- const {_} = useLingui() ++ const { _ } = useLingui() + const t = useTheme() + return ( + void + }): React.ReactNode => { +- const {_} = useLingui() ++ const { _ } = useLingui() + const t = useTheme() + return ( + void +-}): React.ReactNode => { +- const {_} = useLingui() +- const t = useTheme() +- return ( +- +- ) : ( +- +- ) +- } +- label={_(msg`Chat`)} +- bold={isActive} +- onPress={onPress} +- /> +- ) +-} +-ChatMenuItem = React.memo(ChatMenuItem) +- + let NotificationsMenuItem = ({ + isActive, + onPress, +@@ -478,7 +302,7 @@ let NotificationsMenuItem = ({ + isActive: boolean + onPress: () => void + }): React.ReactNode => { +- const {_} = useLingui() ++ const { _ } = useLingui() + const t = useTheme() + const numUnreadNotifications = useUnreadNotifications() + return ( +@@ -495,11 +319,11 @@ let NotificationsMenuItem = ({ + numUnreadNotifications === '' + ? '' + : _( +- msg`${plural(numUnreadNotifications ?? 0, { +- one: '# unread item', +- other: '# unread items', +- })}` || '', +- ) ++ msg`${plural(numUnreadNotifications ?? 0, { ++ one: '# unread item', ++ other: '# unread items', ++ })}` || '', ++ ) + } + count={numUnreadNotifications} + bold={isActive} +@@ -509,72 +333,6 @@ let NotificationsMenuItem = ({ + } + NotificationsMenuItem = React.memo(NotificationsMenuItem) + +-let FeedsMenuItem = ({ +- isActive, +- onPress, +-}: { +- isActive: boolean +- onPress: () => void +-}): React.ReactNode => { +- const {_} = useLingui() +- const t = useTheme() +- return ( +- +- ) : ( +- +- ) +- } +- label={_(msg`Feeds`)} +- bold={isActive} +- onPress={onPress} +- /> +- ) +-} +-FeedsMenuItem = React.memo(FeedsMenuItem) +- +-let ListsMenuItem = ({onPress}: {onPress: () => void}): React.ReactNode => { +- const {_} = useLingui() +- const t = useTheme() +- +- return ( +- } +- label={_(msg`Lists`)} +- onPress={onPress} +- /> +- ) +-} +-ListsMenuItem = React.memo(ListsMenuItem) +- +-let BookmarksMenuItem = ({ +- isActive, +- onPress, +-}: { +- isActive: boolean +- onPress: () => void +-}): React.ReactNode => { +- const {_} = useLingui() +- const t = useTheme() +- +- return ( +- +- ) : ( +- +- ) +- } +- label={_(msg({message: 'Saved', context: 'link to bookmarks screen'}))} +- onPress={onPress} +- /> +- ) +-} +-BookmarksMenuItem = React.memo(BookmarksMenuItem) +- + let ProfileMenuItem = ({ + isActive, + onPress, +@@ -582,7 +340,7 @@ let ProfileMenuItem = ({ + isActive: boolean + onPress: () => void + }): React.ReactNode => { +- const {_} = useLingui() ++ const { _ } = useLingui() + const t = useTheme() + return ( + void}): React.ReactNode => { +- const {_} = useLingui() ++let SettingsMenuItem = ({ onPress }: { onPress: () => void }): React.ReactNode => { ++ const { _ } = useLingui() + const t = useTheme() + return ( + void}): React.ReactNode => { + } + SettingsMenuItem = React.memo(SettingsMenuItem) + +-function MenuItem({icon, label, count, bold, onPress}: MenuItemProps) { ++function MenuItem({ icon, label, count, bold, onPress }: MenuItemProps) { + const t = useTheme() + return ( + +- +- +- You can also discover new Custom Feeds to follow. +- +- + + + ) +diff --git a/src/view/com/posts/PostFeed.tsx b/src/view/com/posts/PostFeed.tsx +index 4f25468c9..c35ad1c1a 100644 +--- a/src/view/com/posts/PostFeed.tsx ++++ b/src/view/com/posts/PostFeed.tsx +@@ -543,14 +543,6 @@ let PostFeed = ({ + }) + } + } else if (feedKind === 'following') { +- if (sliceIndex === 0) { +- // Show composer prompt for Following feed +- if (hasSession && gate('show_composer_prompt')) { +- arr.push({ +- type: 'composerPrompt', +- key: 'composerPrompt-' + sliceIndex, +- }) +- } + } + } else if (feedKind === 'profile') { + if (sliceIndex === 5) {