test gemini
This commit is contained in:
@@ -1,22 +1,8 @@
|
||||
diff --git a/Dockerfile b/Dockerfile
|
||||
index 371e8402c..2e139503e 100644
|
||||
--- a/Dockerfile
|
||||
+++ b/Dockerfile
|
||||
@@ -66,7 +66,8 @@ RUN \. "$NVM_DIR/nvm.sh" && \
|
||||
echo "EXPO_PUBLIC_BUNDLE_DATE=$(date -u +"%y%m%d%H")" >> .env && \
|
||||
echo "EXPO_PUBLIC_SENTRY_DSN=$EXPO_PUBLIC_SENTRY_DSN" >> .env && \
|
||||
npm install --global yarn && \
|
||||
- yarn && \
|
||||
+ yarn config set registry https://registry.npmjs.org/ && \
|
||||
+ yarn install --frozen-lockfile --network-timeout 100000 && \
|
||||
yarn intl:build 2>&1 | tee i18n.log && \
|
||||
if grep -q "invalid syntax" "i18n.log"; then echo "\n\nFound compilation errors!\n\n" && exit 1; else echo "\n\nNo compile errors!\n\n"; fi && \
|
||||
SENTRY_AUTH_TOKEN=$SENTRY_AUTH_TOKEN SENTRY_RELEASE=$EXPO_PUBLIC_RELEASE_VERSION SENTRY_DIST=$EXPO_PUBLIC_BUNDLE_IDENTIFIER yarn build-web
|
||||
diff --git a/app.config.js b/app.config.js
|
||||
index 246d8abd3..a6582864b 100644
|
||||
index 246d8abd3..0e33bf6ac 100644
|
||||
--- a/app.config.js
|
||||
+++ b/app.config.js
|
||||
@@ -33,8 +33,8 @@ module.exports = function (_config) {
|
||||
@@ -33,27 +33,32 @@ module.exports = function (_config) {
|
||||
return {
|
||||
expo: {
|
||||
version: VERSION,
|
||||
@@ -27,7 +13,11 @@ index 246d8abd3..a6582864b 100644
|
||||
scheme: 'bluesky',
|
||||
owner: 'blueskysocial',
|
||||
runtimeVersion: {
|
||||
@@ -45,15 +45,20 @@ module.exports = function (_config) {
|
||||
policy: 'appVersion',
|
||||
},
|
||||
- icon: './assets/app-icons/ios_icon_default_next.png',
|
||||
+ icon: './assets/icon.png',
|
||||
userInterfaceStyle: 'automatic',
|
||||
primaryColor: '#1083fe',
|
||||
newArchEnabled: false,
|
||||
ios: {
|
||||
@@ -68,7 +58,17 @@ index 246d8abd3..a6582864b 100644
|
||||
intentFilters: [
|
||||
{
|
||||
action: 'VIEW',
|
||||
@@ -220,7 +225,7 @@ module.exports = function (_config) {
|
||||
@@ -213,19 +218,19 @@ module.exports = function (_config) {
|
||||
: undefined,
|
||||
codeSigningMetadata: UPDATES_ENABLED
|
||||
? {
|
||||
- keyid: 'main',
|
||||
- alg: 'rsa-v1_5-sha256',
|
||||
- }
|
||||
+ keyid: 'main',
|
||||
+ alg: 'rsa-v1_5-sha256',
|
||||
+ }
|
||||
: undefined,
|
||||
checkAutomatically: 'NEVER',
|
||||
},
|
||||
plugins: [
|
||||
@@ -77,6 +77,12 @@ index 246d8abd3..a6582864b 100644
|
||||
'expo-localization',
|
||||
'expo-web-browser',
|
||||
[
|
||||
'react-native-edge-to-edge',
|
||||
- {android: {enforceNavigationBarContrast: false}},
|
||||
+ { android: { enforceNavigationBarContrast: false } },
|
||||
],
|
||||
USE_SENTRY && [
|
||||
'@sentry/react-native/expo',
|
||||
@@ -239,6 +244,11 @@ module.exports = function (_config) {
|
||||
'expo-build-properties',
|
||||
{
|
||||
@@ -109,6 +115,15 @@ index 246d8abd3..a6582864b 100644
|
||||
enableFullScreenImage_legacy: true,
|
||||
backgroundColor: '#ffffff',
|
||||
image: './assets/splash.png',
|
||||
@@ -386,7 +400,7 @@ module.exports = function (_config) {
|
||||
},
|
||||
},
|
||||
],
|
||||
- ['expo-screen-orientation', {initialOrientation: 'PORTRAIT_UP'}],
|
||||
+ ['expo-screen-orientation', { initialOrientation: 'PORTRAIT_UP' }],
|
||||
['expo-location'],
|
||||
].filter(Boolean),
|
||||
extra: {
|
||||
@@ -394,29 +408,30 @@ module.exports = function (_config) {
|
||||
build: {
|
||||
experimental: {
|
||||
|
||||
@@ -1,27 +1,8 @@
|
||||
diff --git a/src/view/com/posts/PostFeed.tsx b/src/view/com/posts/PostFeed.tsx
|
||||
index 4f25468c9..95b183dcc 100644
|
||||
--- a/src/view/com/posts/PostFeed.tsx
|
||||
+++ b/src/view/com/posts/PostFeed.tsx
|
||||
@@ -298,8 +298,13 @@ let PostFeed = ({
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
+ const errorMsg = String(e)
|
||||
+ // Skip errors for missing repos (deleted accounts)
|
||||
+ if (errorMsg.includes('Could not find repo')) {
|
||||
+ return
|
||||
+ }
|
||||
if (!isNetworkError(e)) {
|
||||
- logger.error('Poll latest failed', {feed, message: String(e)})
|
||||
+ logger.error('Poll latest failed', {feed, message: errorMsg})
|
||||
}
|
||||
}
|
||||
})
|
||||
diff --git a/src/view/screens/PrivacyPolicy.tsx b/src/view/screens/PrivacyPolicy.tsx
|
||||
index a89eaadc4..c3a8b6114 100644
|
||||
index a89eaadc4..1da393f03 100644
|
||||
--- a/src/view/screens/PrivacyPolicy.tsx
|
||||
+++ b/src/view/screens/PrivacyPolicy.tsx
|
||||
@@ -1,51 +1,95 @@
|
||||
@@ -1,52 +1,13 @@
|
||||
import React from 'react'
|
||||
-import {View} from 'react-native'
|
||||
-import {msg, Trans} from '@lingui/macro'
|
||||
@@ -38,7 +19,7 @@ index a89eaadc4..c3a8b6114 100644
|
||||
-import {TextLink} from '#/view/com/util/Link'
|
||||
-import {Text} from '#/view/com/util/text/Text'
|
||||
-import {ScrollView} from '#/view/com/util/Views'
|
||||
+import { ScrollView } from 'react-native'
|
||||
+import { WebView } from 'react-native-webview'
|
||||
import * as Layout from '#/components/Layout'
|
||||
-import {ViewHeader} from '../com/util/ViewHeader'
|
||||
-
|
||||
@@ -54,13 +35,9 @@ index a89eaadc4..c3a8b6114 100644
|
||||
- }, [setMinimalShellMode]),
|
||||
- )
|
||||
+import {useSetTitle} from '#/lib/hooks/useSetTitle'
|
||||
+import {atoms as a, useTheme} from '#/alf'
|
||||
+import {Text} from '#/components/Typography'
|
||||
+
|
||||
|
||||
+export function PrivacyPolicyScreen() {
|
||||
+ useSetTitle('Privacy Policy')
|
||||
+ const t = useTheme()
|
||||
|
||||
return (
|
||||
<Layout.Screen>
|
||||
- <ViewHeader title={_(msg`Privacy Policy`)} />
|
||||
@@ -78,93 +55,16 @@ index a89eaadc4..c3a8b6114 100644
|
||||
- </Text>
|
||||
- </View>
|
||||
- <View style={s.footerSpacer} />
|
||||
+ <ScrollView
|
||||
+ style={[a.flex_1, {backgroundColor: t.palette.white}]}
|
||||
+ contentContainerStyle={[a.p_lg, a.pt_5xl, a.pb_5xl]}>
|
||||
+ <Text style={[a.text_2xl, a.font_bold, a.mb_lg]}>Privacy Policy</Text>
|
||||
+
|
||||
+ <Text style={[a.mb_md]}>
|
||||
+ This application (hereinafter referred to as "the App") respects user privacy and is committed to protecting personal information.
|
||||
+ </Text>
|
||||
+
|
||||
+ <Text style={[a.text_lg, a.font_bold, a.mt_lg, a.mb_md]}>1. Information We Collect</Text>
|
||||
+ <Text style={[a.mb_md]}>
|
||||
+ The App is a decentralized social network using the AT Protocol.
|
||||
+ Information posted by users is stored on the selected server (PDS).
|
||||
+ </Text>
|
||||
+
|
||||
+ <Text style={[a.text_lg, a.font_bold, a.mt_lg, a.mb_md]}>2. Use of Information</Text>
|
||||
+ <Text style={[a.mb_md]}>
|
||||
+ The collected information is used for the following purposes:
|
||||
+ {'\n'}- Providing and operating the service
|
||||
+ {'\n'}- User support
|
||||
+ {'\n'}- Service improvement
|
||||
+ </Text>
|
||||
+
|
||||
+ <Text style={[a.text_lg, a.font_bold, a.mt_lg, a.mb_md]}>3. Third-Party Disclosure</Text>
|
||||
+ <Text style={[a.mb_md]}>
|
||||
+ The App will not provide users' personal information to third parties without user consent, except as required by law.
|
||||
+ </Text>
|
||||
+
|
||||
+ <Text style={[a.text_lg, a.font_bold, a.mt_lg, a.mb_md]}>4. Security</Text>
|
||||
+ <Text style={[a.mb_md]}>
|
||||
+ The App takes appropriate security measures to protect personal information.
|
||||
+ </Text>
|
||||
+
|
||||
+ <Text style={[a.text_lg, a.font_bold, a.mt_lg, a.mb_md]}>5. Contact</Text>
|
||||
+ <Text style={[a.mb_md]}>
|
||||
+ For questions regarding this Privacy Policy, please contact us through the support link in the settings screen.
|
||||
+ </Text>
|
||||
+
|
||||
+ <Text style={[a.text_lg, a.font_bold, a.mt_5xl, a.mb_md]}>日本語訳(参考)</Text>
|
||||
+
|
||||
+ <Text style={[a.text_xl, a.font_bold, a.mb_lg]}>プライバシーポリシー</Text>
|
||||
+
|
||||
+ <Text style={[a.mb_md]}>
|
||||
+ 本アプリケーション(以下「本アプリ」)は、ユーザーのプライバシーを尊重し、個人情報の保護に努めます。
|
||||
+ </Text>
|
||||
+
|
||||
+ <Text style={[a.text_lg, a.font_bold, a.mt_lg, a.mb_md]}>1. 収集する情報</Text>
|
||||
+ <Text style={[a.mb_md]}>
|
||||
+ 本アプリは、ATプロトコルを使用した分散型ソーシャルネットワークです。
|
||||
+ ユーザーが投稿した情報は、選択したサーバー(PDS)に保存されます。
|
||||
+ </Text>
|
||||
+
|
||||
+ <Text style={[a.text_lg, a.font_bold, a.mt_lg, a.mb_md]}>2. 情報の利用目的</Text>
|
||||
+ <Text style={[a.mb_md]}>
|
||||
+ 収集した情報は、以下の目的で利用されます:
|
||||
+ {'\n'}- サービスの提供・運営
|
||||
+ {'\n'}- ユーザーサポート
|
||||
+ {'\n'}- サービスの改善
|
||||
+ </Text>
|
||||
+
|
||||
+ <Text style={[a.text_lg, a.font_bold, a.mt_lg, a.mb_md]}>3. 情報の第三者提供</Text>
|
||||
+ <Text style={[a.mb_md]}>
|
||||
+ 本アプリは、ユーザーの個人情報を、法令に基づく場合を除き、
|
||||
+ ユーザーの同意なく第三者に提供することはありません。
|
||||
+ </Text>
|
||||
+
|
||||
+ <Text style={[a.text_lg, a.font_bold, a.mt_lg, a.mb_md]}>4. セキュリティ</Text>
|
||||
+ <Text style={[a.mb_md]}>
|
||||
+ 本アプリは、個人情報の保護のため、適切な安全対策を講じます。
|
||||
+ </Text>
|
||||
+
|
||||
+ <Text style={[a.text_lg, a.font_bold, a.mt_lg, a.mb_md]}>5. お問い合わせ</Text>
|
||||
+ <Text style={[a.mb_md]}>
|
||||
+ プライバシーポリシーに関するご質問は、設定画面のサポートリンクからお問い合わせください。
|
||||
+ </Text>
|
||||
+
|
||||
+ <Text style={[a.text_sm, a.mt_xl, {color: t.palette.contrast_500}]}>
|
||||
+ Last Updated: December 7, 2025
|
||||
+ </Text>
|
||||
</ScrollView>
|
||||
- </ScrollView>
|
||||
+ <WebView source={{ uri: 'https://syu.is/about/support/privacy-policy' }} style={{ flex: 1 }} />
|
||||
</Layout.Screen>
|
||||
)
|
||||
}
|
||||
diff --git a/src/view/screens/TermsOfService.tsx b/src/view/screens/TermsOfService.tsx
|
||||
index d843c713c..3d2323f73 100644
|
||||
index d843c713c..b81767bd5 100644
|
||||
--- a/src/view/screens/TermsOfService.tsx
|
||||
+++ b/src/view/screens/TermsOfService.tsx
|
||||
@@ -1,49 +1,110 @@
|
||||
@@ -1,50 +1,13 @@
|
||||
import React from 'react'
|
||||
-import {View} from 'react-native'
|
||||
-import {msg, Trans} from '@lingui/macro'
|
||||
@@ -181,7 +81,7 @@ index d843c713c..3d2323f73 100644
|
||||
-import {TextLink} from '#/view/com/util/Link'
|
||||
-import {Text} from '#/view/com/util/text/Text'
|
||||
-import {ScrollView} from '#/view/com/util/Views'
|
||||
+import { ScrollView } from 'react-native'
|
||||
+import { WebView } from 'react-native-webview'
|
||||
import * as Layout from '#/components/Layout'
|
||||
-import {ViewHeader} from '../com/util/ViewHeader'
|
||||
-
|
||||
@@ -197,13 +97,9 @@ index d843c713c..3d2323f73 100644
|
||||
- }, [setMinimalShellMode]),
|
||||
- )
|
||||
+import {useSetTitle} from '#/lib/hooks/useSetTitle'
|
||||
+import {atoms as a, useTheme} from '#/alf'
|
||||
+import {Text} from '#/components/Typography'
|
||||
+
|
||||
|
||||
+export function TermsOfServiceScreen() {
|
||||
+ useSetTitle('Terms of Service')
|
||||
+ const t = useTheme()
|
||||
|
||||
return (
|
||||
<Layout.Screen>
|
||||
- <ViewHeader title={_(msg`Terms of Service`)} />
|
||||
@@ -219,100 +115,8 @@ index d843c713c..3d2323f73 100644
|
||||
- </Text>
|
||||
- </View>
|
||||
- <View style={s.footerSpacer} />
|
||||
+ <ScrollView
|
||||
+ style={[a.flex_1, {backgroundColor: t.palette.white}]}
|
||||
+ contentContainerStyle={[a.p_lg, a.pt_5xl, a.pb_5xl]}>
|
||||
+ <Text style={[a.text_2xl, a.font_bold, a.mb_lg]}>Terms of Service</Text>
|
||||
+
|
||||
+ <Text style={[a.mb_md]}>
|
||||
+ These Terms of Service (hereinafter referred to as "these Terms") set forth the conditions for using this application (hereinafter referred to as "the App").
|
||||
+ </Text>
|
||||
+
|
||||
+ <Text style={[a.text_lg, a.font_bold, a.mt_lg, a.mb_md]}>Article 1 (Application)</Text>
|
||||
+ <Text style={[a.mb_md]}>
|
||||
+ These Terms shall apply to all relationships between users and the provider of the App regarding the use of the App.
|
||||
+ </Text>
|
||||
+
|
||||
+ <Text style={[a.text_lg, a.font_bold, a.mt_lg, a.mb_md]}>Article 2 (User Registration)</Text>
|
||||
+ <Text style={[a.mb_md]}>
|
||||
+ Use of the App requires an AT Protocol-compatible account.
|
||||
+ Registration information must be kept accurate and up-to-date.
|
||||
+ </Text>
|
||||
+
|
||||
+ <Text style={[a.text_lg, a.font_bold, a.mt_lg, a.mb_md]}>Article 3 (Prohibited Acts)</Text>
|
||||
+ <Text style={[a.mb_md]}>
|
||||
+ Users shall not engage in the following acts when using the App:
|
||||
+ {'\n'}- Acts that violate laws or public order and morals
|
||||
+ {'\n'}- Acts related to criminal activity
|
||||
+ {'\n'}- Acts that infringe upon the rights of other users or third parties
|
||||
+ {'\n'}- Acts that interfere with the operation of the App
|
||||
+ {'\n'}- Unauthorized access or attempts thereof
|
||||
+ </Text>
|
||||
+
|
||||
+ <Text style={[a.text_lg, a.font_bold, a.mt_lg, a.mb_md]}>Article 4 (Disclaimer)</Text>
|
||||
+ <Text style={[a.mb_md]}>
|
||||
+ The App is a decentralized service using the AT Protocol.
|
||||
+ The provider makes no warranties, express or implied, regarding the App.
|
||||
+ </Text>
|
||||
+
|
||||
+ <Text style={[a.text_lg, a.font_bold, a.mt_lg, a.mb_md]}>Article 5 (Changes to Terms)</Text>
|
||||
+ <Text style={[a.mb_md]}>
|
||||
+ The provider may change these Terms without obtaining user consent when deemed necessary.
|
||||
+ </Text>
|
||||
+
|
||||
+ <Text style={[a.text_lg, a.font_bold, a.mt_lg, a.mb_md]}>Article 6 (Contact)</Text>
|
||||
+ <Text style={[a.mb_md]}>
|
||||
+ For questions regarding these Terms, please contact us through the support link in the settings screen.
|
||||
+ </Text>
|
||||
+
|
||||
+ <Text style={[a.text_lg, a.font_bold, a.mt_5xl, a.mb_md]}>日本語訳(参考)</Text>
|
||||
+
|
||||
+ <Text style={[a.text_xl, a.font_bold, a.mb_lg]}>利用規約</Text>
|
||||
+
|
||||
+ <Text style={[a.mb_md]}>
|
||||
+ 本利用規約(以下「本規約」)は、本アプリケーション(以下「本アプリ」)の利用条件を定めるものです。
|
||||
+ </Text>
|
||||
+
|
||||
+ <Text style={[a.text_lg, a.font_bold, a.mt_lg, a.mb_md]}>第1条(適用)</Text>
|
||||
+ <Text style={[a.mb_md]}>
|
||||
+ 本規約は、ユーザーと本アプリの提供者との間の本アプリの利用に関わる一切の関係に適用されます。
|
||||
+ </Text>
|
||||
+
|
||||
+ <Text style={[a.text_lg, a.font_bold, a.mt_lg, a.mb_md]}>第2条(利用登録)</Text>
|
||||
+ <Text style={[a.mb_md]}>
|
||||
+ 本アプリの利用にあたっては、ATプロトコル対応のアカウントが必要です。
|
||||
+ 登録情報は正確かつ最新の状態に保つ必要があります。
|
||||
+ </Text>
|
||||
+
|
||||
+ <Text style={[a.text_lg, a.font_bold, a.mt_lg, a.mb_md]}>第3条(禁止事項)</Text>
|
||||
+ <Text style={[a.mb_md]}>
|
||||
+ ユーザーは、本アプリの利用にあたり、以下の行為をしてはなりません:
|
||||
+ {'\n'}- 法令または公序良俗に違反する行為
|
||||
+ {'\n'}- 犯罪行為に関連する行為
|
||||
+ {'\n'}- 他のユーザーまたは第三者の権利を侵害する行為
|
||||
+ {'\n'}- 本アプリの運営を妨害する行為
|
||||
+ {'\n'}- 不正アクセスまたはこれを試みる行為
|
||||
+ </Text>
|
||||
+
|
||||
+ <Text style={[a.text_lg, a.font_bold, a.mt_lg, a.mb_md]}>第4条(免責事項)</Text>
|
||||
+ <Text style={[a.mb_md]}>
|
||||
+ 本アプリは、ATプロトコルを使用した分散型サービスです。
|
||||
+ 提供者は、本アプリに関して、明示的・黙示的を問わず、いかなる保証も行いません。
|
||||
+ </Text>
|
||||
+
|
||||
+ <Text style={[a.text_lg, a.font_bold, a.mt_lg, a.mb_md]}>第5条(規約の変更)</Text>
|
||||
+ <Text style={[a.mb_md]}>
|
||||
+ 提供者は、必要と判断した場合、ユーザーの承諾を得ることなく本規約を変更できるものとします。
|
||||
+ </Text>
|
||||
+
|
||||
+ <Text style={[a.text_lg, a.font_bold, a.mt_lg, a.mb_md]}>第6条(お問い合わせ)</Text>
|
||||
+ <Text style={[a.mb_md]}>
|
||||
+ 本規約に関するご質問は、設定画面のサポートリンクからお問い合わせください。
|
||||
+ </Text>
|
||||
+
|
||||
+ <Text style={[a.text_sm, a.mt_xl, {color: t.palette.contrast_500}]}>
|
||||
+ Last Updated: December 7, 2025
|
||||
+ </Text>
|
||||
</ScrollView>
|
||||
- </ScrollView>
|
||||
+ <WebView source={{ uri: 'https://syu.is/about/support/tos' }} style={{ flex: 1 }} />
|
||||
</Layout.Screen>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,44 +1,8 @@
|
||||
diff --git a/src/Navigation.tsx b/src/Navigation.tsx
|
||||
index fa33a9d56..13af087c2 100644
|
||||
--- a/src/Navigation.tsx
|
||||
+++ b/src/Navigation.tsx
|
||||
@@ -62,6 +62,7 @@ import {NotFoundScreen} from '#/view/screens/NotFound'
|
||||
import {NotificationsScreen} from '#/view/screens/Notifications'
|
||||
import {PostThreadScreen} from '#/view/screens/PostThread'
|
||||
import {PrivacyPolicyScreen} from '#/view/screens/PrivacyPolicy'
|
||||
+import {LicenseScreen} from '#/view/screens/License'
|
||||
import {ProfileScreen} from '#/view/screens/Profile'
|
||||
import {ProfileFeedLikedByScreen} from '#/view/screens/ProfileFeedLikedBy'
|
||||
import {Storybook} from '#/view/screens/Storybook'
|
||||
@@ -335,6 +336,11 @@ function commonScreens(Stack: typeof Flat, unreadCountLabel?: string) {
|
||||
getComponent={() => TermsOfServiceScreen}
|
||||
options={{title: title(msg`Terms of Service`)}}
|
||||
/>
|
||||
+ <Stack.Screen
|
||||
+ name="License"
|
||||
+ getComponent={() => LicenseScreen}
|
||||
+ options={{title: title(msg`License`)}}
|
||||
+ />
|
||||
<Stack.Screen
|
||||
name="CommunityGuidelines"
|
||||
getComponent={() => CommunityGuidelinesScreen}
|
||||
diff --git a/src/lib/routes/types.ts b/src/lib/routes/types.ts
|
||||
index c315a8341..9b2f50a83 100644
|
||||
--- a/src/lib/routes/types.ts
|
||||
+++ b/src/lib/routes/types.ts
|
||||
@@ -39,6 +39,7 @@ export type CommonNavigatorParams = {
|
||||
Support: undefined
|
||||
PrivacyPolicy: undefined
|
||||
TermsOfService: undefined
|
||||
+ License: undefined
|
||||
CommunityGuidelines: undefined
|
||||
CopyrightPolicy: undefined
|
||||
LanguageSettings: undefined
|
||||
diff --git a/src/routes.ts b/src/routes.ts
|
||||
index 1ed913bb2..aa6fccc4e 100644
|
||||
index 1ed913bb2..77ea6deca 100644
|
||||
--- a/src/routes.ts
|
||||
+++ b/src/routes.ts
|
||||
@@ -71,8 +71,9 @@ export const router = new Router<AllNavigatableRoutes>({
|
||||
@@ -71,8 +71,8 @@ export const router = new Router<AllNavigatableRoutes>({
|
||||
MiscellaneousNotificationSettings: '/settings/notifications/miscellaneous',
|
||||
// support
|
||||
Support: '/support',
|
||||
@@ -46,12 +10,11 @@ index 1ed913bb2..aa6fccc4e 100644
|
||||
- TermsOfService: '/support/tos',
|
||||
+ PrivacyPolicy: 'https://syu.is/about/support/privacy-policy',
|
||||
+ TermsOfService: 'https://syu.is/about/support/tos',
|
||||
+ License: '/support/license',
|
||||
CommunityGuidelines: '/support/community-guidelines',
|
||||
CopyrightPolicy: '/support/copyright',
|
||||
// hashtags
|
||||
diff --git a/src/view/shell/Drawer.tsx b/src/view/shell/Drawer.tsx
|
||||
index ed2a6cfb7..982c40b55 100644
|
||||
index ed2a6cfb7..2f387b4a8 100644
|
||||
--- a/src/view/shell/Drawer.tsx
|
||||
+++ b/src/view/shell/Drawer.tsx
|
||||
@@ -1,60 +1,50 @@
|
||||
@@ -625,7 +588,7 @@ index ed2a6cfb7..982c40b55 100644
|
||||
]}>
|
||||
<View
|
||||
style={[
|
||||
@@ -686,37 +444,28 @@ function MenuItem({icon, label, count, bold, onPress}: MenuItemProps) {
|
||||
@@ -686,37 +444,23 @@ function MenuItem({icon, label, count, bold, onPress}: MenuItemProps) {
|
||||
}
|
||||
|
||||
function ExtraLinks() {
|
||||
@@ -670,11 +633,6 @@ index ed2a6cfb7..982c40b55 100644
|
||||
+ <Text style={[a.text_md, t.atoms.text_contrast_medium]}>
|
||||
+ <Trans>Privacy Policy</Trans>
|
||||
+ </Text>
|
||||
+ </TouchableOpacity>
|
||||
+ <TouchableOpacity onPress={() => navigation.navigate('License')}>
|
||||
+ <Text style={[a.text_md, t.atoms.text_contrast_medium]}>
|
||||
+ <Trans>License</Trans>
|
||||
+ </Text>
|
||||
+ </TouchableOpacity>
|
||||
</View>
|
||||
)
|
||||
|
||||
@@ -46,72 +46,3 @@ index 3442d1bdf..2b059af52 100644
|
||||
<View style={{height: insets.bottom}} />
|
||||
</ErrorBoundary>
|
||||
</Animated.View>
|
||||
diff --git a/src/view/com/auth/SplashScreen.web.tsx b/src/view/com/auth/SplashScreen.web.tsx
|
||||
index 22dd23d7f..08cd8aa33 100644
|
||||
--- a/src/view/com/auth/SplashScreen.web.tsx
|
||||
+++ b/src/view/com/auth/SplashScreen.web.tsx
|
||||
@@ -3,7 +3,9 @@ import {Pressable, View} from 'react-native'
|
||||
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
|
||||
import {msg, Trans} from '@lingui/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
+import {useNavigation} from '@react-navigation/native'
|
||||
|
||||
+import {NavigationProp} from '#/lib/routes/types'
|
||||
import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
|
||||
import {useKawaiiMode} from '#/state/preferences/kawaii'
|
||||
import {ErrorBoundary} from '#/view/com/util/ErrorBoundary'
|
||||
@@ -93,15 +95,6 @@ export const SplashScreen = ({
|
||||
<Logotype width={161} fill={t.atoms.text.color} />
|
||||
</View>
|
||||
)}
|
||||
-
|
||||
- <Text
|
||||
- style={[
|
||||
- a.text_md,
|
||||
- a.font_semi_bold,
|
||||
- t.atoms.text_contrast_medium,
|
||||
- ]}>
|
||||
- <Trans>What's up?</Trans>
|
||||
- </Text>
|
||||
</View>
|
||||
|
||||
<View
|
||||
@@ -150,7 +143,6 @@ export const SplashScreen = ({
|
||||
|
||||
function Footer() {
|
||||
const t = useTheme()
|
||||
- const {_} = useLingui()
|
||||
|
||||
return (
|
||||
<View
|
||||
@@ -168,26 +160,12 @@ function Footer() {
|
||||
a.flex_1,
|
||||
t.atoms.border_contrast_medium,
|
||||
]}>
|
||||
- <InlineLinkText
|
||||
- label={_(msg`Learn more about Bluesky`)}
|
||||
- to="https://bsky.social">
|
||||
- <Trans>Business</Trans>
|
||||
- </InlineLinkText>
|
||||
- <InlineLinkText
|
||||
- label={_(msg`Read the Bluesky blog`)}
|
||||
- to="https://bsky.social/about/blog">
|
||||
- <Trans>Blog</Trans>
|
||||
- </InlineLinkText>
|
||||
- <InlineLinkText
|
||||
- label={_(msg`See jobs at Bluesky`)}
|
||||
- to="https://bsky.social/about/join">
|
||||
- <Trans comment="Link to a page with job openings at Bluesky">
|
||||
- Jobs
|
||||
- </Trans>
|
||||
- </InlineLinkText>
|
||||
-
|
||||
<View style={a.flex_1} />
|
||||
|
||||
+ <Text style={[a.text_xs, t.atoms.text_contrast_low]}>
|
||||
+ © syui
|
||||
+ </Text>
|
||||
+
|
||||
<AppLanguageDropdown />
|
||||
</View>
|
||||
)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/src/screens/Settings/AboutSettings.tsx b/src/screens/Settings/AboutSettings.tsx
|
||||
index 6b8257b91..bed851753 100644
|
||||
index 6b8257b91..48ba7909e 100644
|
||||
--- a/src/screens/Settings/AboutSettings.tsx
|
||||
+++ b/src/screens/Settings/AboutSettings.tsx
|
||||
@@ -80,7 +80,7 @@ export function AboutSettingsScreen({}: Props) {
|
||||
@@ -7,7 +7,7 @@ index 6b8257b91..bed851753 100644
|
||||
<SettingsList.Container>
|
||||
<SettingsList.LinkItem
|
||||
- to="https://bsky.social/about/support/tos"
|
||||
+ to="/about/support/tos"
|
||||
+ to="https://syu.is/about/support/tos"
|
||||
label={_(msg`Terms of Service`)}>
|
||||
<SettingsList.ItemIcon icon={NewspaperIcon} />
|
||||
<SettingsList.ItemText>
|
||||
@@ -16,16 +16,7 @@ index 6b8257b91..bed851753 100644
|
||||
</SettingsList.LinkItem>
|
||||
<SettingsList.LinkItem
|
||||
- to="https://bsky.social/about/support/privacy-policy"
|
||||
+ to="/about/support/privacy-policy"
|
||||
+ to="https://syu.is/about/support/privacy-policy"
|
||||
label={_(msg`Privacy Policy`)}>
|
||||
<SettingsList.ItemIcon icon={NewspaperIcon} />
|
||||
<SettingsList.ItemText>
|
||||
@@ -96,7 +96,7 @@ export function AboutSettingsScreen({}: Props) {
|
||||
</SettingsList.ItemText>
|
||||
</SettingsList.LinkItem>
|
||||
<SettingsList.LinkItem
|
||||
- to={STATUS_PAGE_URL}
|
||||
+ to="https://syu.is/"
|
||||
label={_(msg`Status Page`)}>
|
||||
<SettingsList.ItemIcon icon={GlobeIcon} />
|
||||
<SettingsList.ItemText>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
--- a/b/src/ageAssurance/index.tsx 2025-12-07 15:18:15
|
||||
+++ b/src/ageAssurance/index.tsx 2025-12-07 15:18:16
|
||||
diff --git a/src/ageAssurance/index.tsx b/src/ageAssurance/index.tsx
|
||||
index 9a0a9c9d5..85d3c64ce 100644
|
||||
--- a/src/ageAssurance/index.tsx
|
||||
+++ b/src/ageAssurance/index.tsx
|
||||
@@ -1,10 +1,10 @@
|
||||
-import {createContext, useCallback, useContext, useEffect, useMemo} from 'react'
|
||||
+import { createContext, useCallback, useContext, useEffect, useMemo } from 'react'
|
||||
@@ -17,7 +19,7 @@
|
||||
import {
|
||||
useAgeAssuranceState,
|
||||
useOnAgeAssuranceAccessUpdate,
|
||||
@@ -14,7 +14,7 @@
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
type AgeAssuranceState,
|
||||
AgeAssuranceStatus,
|
||||
} from '#/ageAssurance/types'
|
||||
@@ -26,7 +28,7 @@
|
||||
|
||||
export {
|
||||
prefetchConfig as prefetchAgeAssuranceConfig,
|
||||
@@ -23,7 +23,7 @@
|
||||
@@ -23,7 +23,7 @@ export {
|
||||
usePatchOtherRequiredData as usePatchAgeAssuranceOtherRequiredData,
|
||||
usePatchServerState as usePatchAgeAssuranceServerState,
|
||||
} from '#/ageAssurance/data'
|
||||
@@ -35,7 +37,7 @@
|
||||
|
||||
const AgeAssuranceStateContext = createContext<{
|
||||
Access: typeof AgeAssuranceAccess
|
||||
@@ -56,7 +56,7 @@
|
||||
@@ -56,7 +56,7 @@ export function useAgeAssurance() {
|
||||
return useContext(AgeAssuranceStateContext)
|
||||
}
|
||||
|
||||
@@ -44,7 +46,7 @@
|
||||
return (
|
||||
<AgeAssuranceDataProvider>
|
||||
<InnerProvider>
|
||||
@@ -66,9 +66,9 @@
|
||||
@@ -66,9 +66,9 @@ export function Provider({children}: {children: React.ReactNode}) {
|
||||
)
|
||||
}
|
||||
|
||||
@@ -56,7 +58,7 @@
|
||||
const getAndRegisterPushToken = useGetAndRegisterPushToken()
|
||||
|
||||
const handleAccessUpdate = useCallback(
|
||||
@@ -82,28 +82,25 @@
|
||||
@@ -82,28 +82,25 @@ function InnerProvider({children}: {children: React.ReactNode}) {
|
||||
useOnAgeAssuranceAccessUpdate(handleAccessUpdate)
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
407
ios/patching/021-social-app-ios-clean-feed.patch
Normal file
407
ios/patching/021-social-app-ios-clean-feed.patch
Normal file
@@ -0,0 +1,407 @@
|
||||
diff --git a/src/view/screens/Home.tsx b/src/view/screens/Home.tsx
|
||||
index e058e2883..0f583c915 100644
|
||||
--- a/src/view/screens/Home.tsx
|
||||
+++ b/src/view/screens/Home.tsx
|
||||
@@ -1,23 +1,16 @@
|
||||
import React from 'react'
|
||||
import {ActivityIndicator, StyleSheet} from 'react-native'
|
||||
import {useFocusEffect} from '@react-navigation/native'
|
||||
-
|
||||
import {PROD_DEFAULT_FEED} from '#/lib/constants'
|
||||
import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
|
||||
import {useOTAUpdates} from '#/lib/hooks/useOTAUpdates'
|
||||
import {useSetTitle} from '#/lib/hooks/useSetTitle'
|
||||
import {useRequestNotificationsPermission} from '#/lib/notifications/notifications'
|
||||
-import {
|
||||
- type HomeTabNavigatorParams,
|
||||
- type NativeStackScreenProps,
|
||||
-} from '#/lib/routes/types'
|
||||
+import {type HomeTabNavigatorParams, type NativeStackScreenProps} from '#/lib/routes/types'
|
||||
import {logEvent} from '#/lib/statsig/statsig'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {emitSoftReset} from '#/state/events'
|
||||
-import {
|
||||
- type SavedFeedSourceInfo,
|
||||
- usePinnedFeedsInfos,
|
||||
-} from '#/state/queries/feed'
|
||||
+import {type SavedFeedSourceInfo, usePinnedFeedsInfos} from '#/state/queries/feed'
|
||||
import {type FeedDescriptor, type FeedParams} from '#/state/queries/post-feed'
|
||||
import {usePreferencesQuery} from '#/state/queries/preferences'
|
||||
import {type UsePreferencesQueryResponse} from '#/state/queries/preferences/types'
|
||||
@@ -27,11 +20,7 @@ import {useLoggedOutViewControls} from '#/state/shell/logged-out'
|
||||
import {useSelectedFeed, useSetSelectedFeed} from '#/state/shell/selected-feed'
|
||||
import {FeedPage} from '#/view/com/feeds/FeedPage'
|
||||
import {HomeHeader} from '#/view/com/home/HomeHeader'
|
||||
-import {
|
||||
- Pager,
|
||||
- type PagerRef,
|
||||
- type RenderTabBarFnProps,
|
||||
-} from '#/view/com/pager/Pager'
|
||||
+import {Pager, type PagerRef, type RenderTabBarFnProps} from '#/view/com/pager/Pager'
|
||||
import {CustomFeedEmptyState} from '#/view/com/posts/CustomFeedEmptyState'
|
||||
import {FollowingEmptyState} from '#/view/com/posts/FollowingEmptyState'
|
||||
import {FollowingEndOfFeed} from '#/view/com/posts/FollowingEndOfFeed'
|
||||
@@ -39,97 +28,60 @@ import {NoFeedsPinned} from '#/screens/Home/NoFeedsPinned'
|
||||
import * as Layout from '#/components/Layout'
|
||||
import {useDemoMode} from '#/storage/hooks/demo-mode'
|
||||
|
||||
+const DEFAULT_PINNED_FEEDS = [{
|
||||
+ feedDescriptor: 'following',
|
||||
+ displayName: 'Following',
|
||||
+ id: 'following',
|
||||
+ type: 'feed',
|
||||
+ savedFeed: undefined,
|
||||
+ pinned: true,
|
||||
+}]
|
||||
+
|
||||
type Props = NativeStackScreenProps<HomeTabNavigatorParams, 'Home' | 'Start'>
|
||||
export function HomeScreen(props: Props) {
|
||||
const {setShowLoggedOut} = useLoggedOutViewControls()
|
||||
const {data: preferences} = usePreferencesQuery()
|
||||
const {currentAccount} = useSession()
|
||||
- const {data: pinnedFeedInfos, isLoading: isPinnedFeedsLoading} =
|
||||
- usePinnedFeedsInfos()
|
||||
+ const {data: pinnedFeedInfos} = usePinnedFeedsInfos()
|
||||
+
|
||||
+ const safePreferences = preferences || { feedViewPrefs: { lab_mergeFeedEnabled: false }, savedFeeds: [] } as any
|
||||
+ const safePinnedFeedInfos = pinnedFeedInfos || DEFAULT_PINNED_FEEDS
|
||||
|
||||
React.useEffect(() => {
|
||||
if (isWeb && !currentAccount) {
|
||||
const getParams = new URLSearchParams(window.location.search)
|
||||
const splash = getParams.get('splash')
|
||||
- if (splash === 'true') {
|
||||
- setShowLoggedOut(true)
|
||||
- return
|
||||
- }
|
||||
+ if (splash === 'true') { setShowLoggedOut(true); return }
|
||||
}
|
||||
-
|
||||
const params = props.route.params
|
||||
- if (
|
||||
- currentAccount &&
|
||||
- props.route.name === 'Start' &&
|
||||
- params?.name &&
|
||||
- params?.rkey
|
||||
- ) {
|
||||
- props.navigation.navigate('StarterPack', {
|
||||
- rkey: params.rkey,
|
||||
- name: params.name,
|
||||
- })
|
||||
+ if (currentAccount && props.route.name === 'Start' && params?.name && params?.rkey) {
|
||||
+ props.navigation.navigate('StarterPack', { rkey: params.rkey, name: params.name })
|
||||
}
|
||||
- }, [
|
||||
- currentAccount,
|
||||
- props.navigation,
|
||||
- props.route.name,
|
||||
- props.route.params,
|
||||
- setShowLoggedOut,
|
||||
- ])
|
||||
+ }, [currentAccount, props.navigation, props.route.name, props.route.params, setShowLoggedOut])
|
||||
|
||||
- if (preferences && pinnedFeedInfos && !isPinnedFeedsLoading) {
|
||||
- return (
|
||||
- <Layout.Screen testID="HomeScreen">
|
||||
- <HomeScreenReady
|
||||
- {...props}
|
||||
- preferences={preferences}
|
||||
- pinnedFeedInfos={pinnedFeedInfos}
|
||||
- />
|
||||
- </Layout.Screen>
|
||||
- )
|
||||
- } else {
|
||||
- return (
|
||||
- <Layout.Screen>
|
||||
- <Layout.Center style={styles.loading}>
|
||||
- <ActivityIndicator size="large" />
|
||||
- </Layout.Center>
|
||||
- </Layout.Screen>
|
||||
- )
|
||||
- }
|
||||
+ return (
|
||||
+ <Layout.Screen testID="HomeScreen">
|
||||
+ <HomeScreenReady {...props} preferences={safePreferences} pinnedFeedInfos={safePinnedFeedInfos as any} />
|
||||
+ </Layout.Screen>
|
||||
+ )
|
||||
}
|
||||
|
||||
-function HomeScreenReady({
|
||||
- preferences,
|
||||
- pinnedFeedInfos,
|
||||
-}: Props & {
|
||||
- preferences: UsePreferencesQueryResponse
|
||||
- pinnedFeedInfos: SavedFeedSourceInfo[]
|
||||
-}) {
|
||||
- const allFeeds = React.useMemo(
|
||||
- () => pinnedFeedInfos.map(f => f.feedDescriptor),
|
||||
- [pinnedFeedInfos],
|
||||
- )
|
||||
- const maybeRawSelectedFeed: FeedDescriptor | undefined =
|
||||
- useSelectedFeed() ?? allFeeds[0]
|
||||
+function HomeScreenReady({preferences, pinnedFeedInfos}: any) {
|
||||
+ const allFeeds = React.useMemo(() => pinnedFeedInfos.map(f => f.feedDescriptor), [pinnedFeedInfos])
|
||||
+ const maybeRawSelectedFeed = useSelectedFeed() ?? allFeeds[0]
|
||||
const setSelectedFeed = useSetSelectedFeed()
|
||||
const maybeFoundIndex = allFeeds.indexOf(maybeRawSelectedFeed)
|
||||
const selectedIndex = Math.max(0, maybeFoundIndex)
|
||||
- const maybeSelectedFeed: FeedDescriptor | undefined = allFeeds[selectedIndex]
|
||||
+ const maybeSelectedFeed = allFeeds[selectedIndex]
|
||||
const requestNotificationsPermission = useRequestNotificationsPermission()
|
||||
-
|
||||
+
|
||||
useSetTitle(pinnedFeedInfos[selectedIndex]?.displayName)
|
||||
useOTAUpdates()
|
||||
-
|
||||
- React.useEffect(() => {
|
||||
- requestNotificationsPermission('Home')
|
||||
- }, [requestNotificationsPermission])
|
||||
+ React.useEffect(() => { requestNotificationsPermission('Home') }, [requestNotificationsPermission])
|
||||
|
||||
const pagerRef = React.useRef<PagerRef>(null)
|
||||
const lastPagerReportedIndexRef = React.useRef(selectedIndex)
|
||||
React.useLayoutEffect(() => {
|
||||
- // Since the pager is not a controlled component, adjust it imperatively
|
||||
- // if the selected index gets out of sync with what it last reported.
|
||||
- // This is supposed to only happen on the web when you use the right nav.
|
||||
if (selectedIndex !== lastPagerReportedIndexRef.current) {
|
||||
lastPagerReportedIndexRef.current = selectedIndex
|
||||
pagerRef.current?.setPage(selectedIndex)
|
||||
@@ -138,205 +90,43 @@ function HomeScreenReady({
|
||||
|
||||
const {hasSession} = useSession()
|
||||
const setMinimalShellMode = useSetMinimalShellMode()
|
||||
- useFocusEffect(
|
||||
- React.useCallback(() => {
|
||||
- setMinimalShellMode(false)
|
||||
- }, [setMinimalShellMode]),
|
||||
- )
|
||||
-
|
||||
- useFocusEffect(
|
||||
- useNonReactiveCallback(() => {
|
||||
- if (maybeSelectedFeed) {
|
||||
- logEvent('home:feedDisplayed', {
|
||||
- index: selectedIndex,
|
||||
- feedType: maybeSelectedFeed.split('|')[0],
|
||||
- feedUrl: maybeSelectedFeed,
|
||||
- reason: 'focus',
|
||||
- })
|
||||
- }
|
||||
- }),
|
||||
- )
|
||||
-
|
||||
- const onPageSelected = React.useCallback(
|
||||
- (index: number) => {
|
||||
- setMinimalShellMode(false)
|
||||
- const maybeFeed = allFeeds[index]
|
||||
-
|
||||
- // Mutate the ref before setting state to avoid the imperative syncing effect
|
||||
- // above from starting a loop on Android when swiping back and forth.
|
||||
- lastPagerReportedIndexRef.current = index
|
||||
- setSelectedFeed(maybeFeed)
|
||||
-
|
||||
- if (maybeFeed) {
|
||||
- logEvent('home:feedDisplayed', {
|
||||
- index,
|
||||
- feedType: maybeFeed.split('|')[0],
|
||||
- feedUrl: maybeFeed,
|
||||
- })
|
||||
- }
|
||||
- },
|
||||
- [setSelectedFeed, setMinimalShellMode, allFeeds],
|
||||
- )
|
||||
-
|
||||
- const onPressSelected = React.useCallback(() => {
|
||||
- emitSoftReset()
|
||||
- }, [])
|
||||
-
|
||||
- const onPageScrollStateChanged = React.useCallback(
|
||||
- (state: 'idle' | 'dragging' | 'settling') => {
|
||||
- 'worklet'
|
||||
- if (state === 'dragging') {
|
||||
- setMinimalShellMode(false)
|
||||
- }
|
||||
- },
|
||||
- [setMinimalShellMode],
|
||||
- )
|
||||
+ useFocusEffect(React.useCallback(() => { setMinimalShellMode(false) }, [setMinimalShellMode]))
|
||||
+
|
||||
+ const onPageSelected = React.useCallback((index) => {
|
||||
+ setMinimalShellMode(false)
|
||||
+ const maybeFeed = allFeeds[index]
|
||||
+ lastPagerReportedIndexRef.current = index
|
||||
+ setSelectedFeed(maybeFeed)
|
||||
+ }, [setSelectedFeed, setMinimalShellMode, allFeeds])
|
||||
+
|
||||
+ const onPressSelected = React.useCallback(() => { emitSoftReset() }, [])
|
||||
+ const onPageScrollStateChanged = React.useCallback((state) => {
|
||||
+ 'worklet'
|
||||
+ if (state === 'dragging') setMinimalShellMode(false)
|
||||
+ }, [setMinimalShellMode])
|
||||
|
||||
const [demoMode] = useDemoMode()
|
||||
-
|
||||
- const renderTabBar = React.useCallback(
|
||||
- (props: RenderTabBarFnProps) => {
|
||||
- if (demoMode) {
|
||||
- return (
|
||||
- <HomeHeader
|
||||
- key="FEEDS_TAB_BAR"
|
||||
- {...props}
|
||||
- testID="homeScreenFeedTabs"
|
||||
- onPressSelected={onPressSelected}
|
||||
- // @ts-ignore
|
||||
- feeds={[{displayName: 'Following'}, {displayName: 'Discover'}]}
|
||||
- />
|
||||
- )
|
||||
- }
|
||||
- return (
|
||||
- <HomeHeader
|
||||
- key="FEEDS_TAB_BAR"
|
||||
- {...props}
|
||||
- testID="homeScreenFeedTabs"
|
||||
- onPressSelected={onPressSelected}
|
||||
- feeds={pinnedFeedInfos}
|
||||
- />
|
||||
- )
|
||||
- },
|
||||
- [onPressSelected, pinnedFeedInfos, demoMode],
|
||||
- )
|
||||
-
|
||||
- const renderFollowingEmptyState = React.useCallback(() => {
|
||||
- return <FollowingEmptyState />
|
||||
- }, [])
|
||||
-
|
||||
- const renderCustomFeedEmptyState = React.useCallback(() => {
|
||||
- return <CustomFeedEmptyState />
|
||||
- }, [])
|
||||
-
|
||||
- const homeFeedParams = React.useMemo<FeedParams>(() => {
|
||||
- return {
|
||||
- mergeFeedEnabled: Boolean(preferences.feedViewPrefs.lab_mergeFeedEnabled),
|
||||
- mergeFeedSources: preferences.feedViewPrefs.lab_mergeFeedEnabled
|
||||
- ? preferences.savedFeeds
|
||||
- .filter(f => f.type === 'feed' || f.type === 'list')
|
||||
- .map(f => f.value)
|
||||
- : [],
|
||||
- }
|
||||
- }, [preferences])
|
||||
-
|
||||
- if (demoMode) {
|
||||
- return (
|
||||
- <Pager
|
||||
- ref={pagerRef}
|
||||
- testID="homeScreen"
|
||||
- onPageSelected={onPageSelected}
|
||||
- onPageScrollStateChanged={onPageScrollStateChanged}
|
||||
- renderTabBar={renderTabBar}
|
||||
- initialPage={selectedIndex}>
|
||||
- <FeedPage
|
||||
- testID="demoFeedPage"
|
||||
- isPageFocused
|
||||
- isPageAdjacent={false}
|
||||
- feed="demo"
|
||||
- renderEmptyState={renderCustomFeedEmptyState}
|
||||
- feedInfo={pinnedFeedInfos[0]}
|
||||
- />
|
||||
- <FeedPage
|
||||
- testID="customFeedPage"
|
||||
- isPageFocused
|
||||
- isPageAdjacent={false}
|
||||
- feed={`feedgen|${PROD_DEFAULT_FEED('whats-hot')}`}
|
||||
- renderEmptyState={renderCustomFeedEmptyState}
|
||||
- feedInfo={pinnedFeedInfos[0]}
|
||||
- />
|
||||
- </Pager>
|
||||
- )
|
||||
- }
|
||||
-
|
||||
- return hasSession ? (
|
||||
- <Pager
|
||||
- key={allFeeds.join(',')}
|
||||
- ref={pagerRef}
|
||||
- testID="homeScreen"
|
||||
- initialPage={selectedIndex}
|
||||
- onPageSelected={onPageSelected}
|
||||
- onPageScrollStateChanged={onPageScrollStateChanged}
|
||||
- renderTabBar={renderTabBar}>
|
||||
- {pinnedFeedInfos.length ? (
|
||||
- pinnedFeedInfos.map((feedInfo, index) => {
|
||||
+ const renderTabBar = React.useCallback((props) => {
|
||||
+ return <HomeHeader key="FEEDS_TAB_BAR" {...props} testID="homeScreenFeedTabs" onPressSelected={onPressSelected} feeds={pinnedFeedInfos} />
|
||||
+ }, [onPressSelected, pinnedFeedInfos])
|
||||
+
|
||||
+ const renderFollowingEmptyState = React.useCallback(() => <FollowingEmptyState />, [])
|
||||
+ const renderCustomFeedEmptyState = React.useCallback(() => <CustomFeedEmptyState />, [])
|
||||
+
|
||||
+ const homeFeedParams = React.useMemo(() => ({
|
||||
+ mergeFeedEnabled: false, mergeFeedSources: []
|
||||
+ }), [preferences])
|
||||
+
|
||||
+ return (
|
||||
+ <Pager ref={pagerRef} testID="homeScreen" initialPage={selectedIndex} onPageSelected={onPageSelected} onPageScrollStateChanged={onPageScrollStateChanged} renderTabBar={renderTabBar}>
|
||||
+ {pinnedFeedInfos.map((feedInfo, index) => {
|
||||
const feed = feedInfo.feedDescriptor
|
||||
if (feed === 'following') {
|
||||
- return (
|
||||
- <FeedPage
|
||||
- key={feed}
|
||||
- testID="followingFeedPage"
|
||||
- isPageFocused={maybeSelectedFeed === feed}
|
||||
- isPageAdjacent={Math.abs(selectedIndex - index) === 1}
|
||||
- feed={feed}
|
||||
- feedParams={homeFeedParams}
|
||||
- renderEmptyState={renderFollowingEmptyState}
|
||||
- renderEndOfFeed={FollowingEndOfFeed}
|
||||
- feedInfo={feedInfo}
|
||||
- />
|
||||
- )
|
||||
+ return <FeedPage key={feed} testID="followingFeedPage" isPageFocused={maybeSelectedFeed === feed} isPageAdjacent={Math.abs(selectedIndex - index) === 1} feed={feed} feedParams={homeFeedParams} renderEmptyState={renderFollowingEmptyState} renderEndOfFeed={FollowingEndOfFeed} feedInfo={feedInfo} />
|
||||
}
|
||||
- const savedFeedConfig = feedInfo.savedFeed
|
||||
- return (
|
||||
- <FeedPage
|
||||
- key={feed}
|
||||
- testID="customFeedPage"
|
||||
- isPageFocused={maybeSelectedFeed === feed}
|
||||
- isPageAdjacent={Math.abs(selectedIndex - index) === 1}
|
||||
- feed={feed}
|
||||
- renderEmptyState={renderCustomFeedEmptyState}
|
||||
- savedFeedConfig={savedFeedConfig}
|
||||
- feedInfo={feedInfo}
|
||||
- />
|
||||
- )
|
||||
- })
|
||||
- ) : (
|
||||
- <NoFeedsPinned preferences={preferences} />
|
||||
- )}
|
||||
- </Pager>
|
||||
- ) : (
|
||||
- <Pager
|
||||
- testID="homeScreen"
|
||||
- onPageSelected={onPageSelected}
|
||||
- onPageScrollStateChanged={onPageScrollStateChanged}
|
||||
- renderTabBar={renderTabBar}>
|
||||
- <FeedPage
|
||||
- testID="customFeedPage"
|
||||
- isPageFocused
|
||||
- isPageAdjacent={false}
|
||||
- feed={`feedgen|${PROD_DEFAULT_FEED('whats-hot')}`}
|
||||
- renderEmptyState={renderCustomFeedEmptyState}
|
||||
- feedInfo={pinnedFeedInfos[0]}
|
||||
- />
|
||||
+ return <FeedPage key={feed} testID="customFeedPage" isPageFocused={maybeSelectedFeed === feed} isPageAdjacent={Math.abs(selectedIndex - index) === 1} feed={feed} renderEmptyState={renderCustomFeedEmptyState} savedFeedConfig={feedInfo.savedFeed} feedInfo={feedInfo} />
|
||||
+ })}
|
||||
</Pager>
|
||||
)
|
||||
}
|
||||
-
|
||||
-const styles = StyleSheet.create({
|
||||
- loading: {
|
||||
- height: '100%',
|
||||
- alignContent: 'center',
|
||||
- justifyContent: 'center',
|
||||
- paddingBottom: 100,
|
||||
- },
|
||||
-})
|
||||
+const styles = StyleSheet.create({ loading: { height: '100%', alignContent: 'center', justifyContent: 'center', paddingBottom: 100 } })
|
||||
Reference in New Issue
Block a user