ai/at
1
0

fix social-app feed view patch

This commit is contained in:
2025-12-12 16:16:46 +09:00
parent 6a02d661fb
commit 9f393f55a9
15 changed files with 661 additions and 207 deletions

View File

@@ -81,8 +81,7 @@ index 231447b4f..a44b3da05 100644
- 'at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.generator/whats-hot'
+ 'at://did:plc:6qyecktefllvenje24fcxnie/app.bsky.feed.generator/app'
export const VIDEO_FEED_URI =
- 'at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.generator/thevids'
+ 'at://did:plc:6qyecktefllvenje24fcxnie/app.bsky.feed.generator/app'
'at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.generator/thevids'
export const STAGING_VIDEO_FEED_URI =
'at://did:plc:yofh3kx63drvfljkibw5zuxo/app.bsky.feed.generator/thevids'
export const VIDEO_FEED_URIS = [VIDEO_FEED_URI, STAGING_VIDEO_FEED_URI]

View File

@@ -1,5 +1,5 @@
diff --git a/src/screens/Settings/AboutSettings.tsx b/src/screens/Settings/AboutSettings.tsx
index 6b8257b91..35202224b 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) {
@@ -21,26 +21,25 @@ index 6b8257b91..35202224b 100644
<SettingsList.ItemIcon icon={NewspaperIcon} />
<SettingsList.ItemText>
diff --git a/src/screens/Takendown.tsx b/src/screens/Takendown.tsx
index dd319a4c6..0e80f956a 100644
index 77f219e55..53f5e0cc0 100644
--- a/src/screens/Takendown.tsx
+++ b/src/screens/Takendown.tsx
@@ -223,11 +223,11 @@ export function Takendown() {
@@ -217,10 +217,10 @@ export function Takendown() {
<Trans>
Your account was found to be in violation of the{' '}
<InlineLinkText
<SimpleInlineLinkText
- label={_(msg`Bluesky Social Terms of Service`)}
- to="https://bsky.social/about/support/tos"
+ label={_(msg`syu.is Terms of Service`)}
+ to="https://syu.is/about/support/tos"
style={[a.text_md, a.leading_normal]}
overridePresentation>
style={[a.text_md, a.leading_normal]}>
- Bluesky Social Terms of Service
+ syu.is Terms of Service
</InlineLinkText>
</SimpleInlineLinkText>
. You have been sent an email outlining the specific violation
and suspension period, if applicable. You can appeal this
diff --git a/src/view/screens/Home.tsx b/src/view/screens/Home.tsx
index e058e2883..0f583c915 100644
index e058e2883..7a355cf6c 100644
--- a/src/view/screens/Home.tsx
+++ b/src/view/screens/Home.tsx
@@ -1,23 +1,16 @@
@@ -82,17 +81,42 @@ index e058e2883..0f583c915 100644
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'
@@ -39,97 +28,87 @@ import {NoFeedsPinned} from '#/screens/Home/NoFeedsPinned'
import * as Layout from '#/components/Layout'
import {useDemoMode} from '#/storage/hooks/demo-mode'
+const DEFAULT_PINNED_FEEDS = [{
+const SYU_IS_FEED_URI = 'at://did:plc:6qyecktefllvenje24fcxnie/app.bsky.feed.generator/app'
+
+const DEFAULT_PINNED_FEEDS: any[] = [{
+ feedDescriptor: 'following',
+ displayName: 'Following',
+ id: 'following',
+ uri: 'following',
+ type: 'feed',
+ savedFeed: undefined,
+ pinned: true,
+ route: { href: '/', name: 'Home', params: {} },
+ cid: '',
+ avatar: '',
+ creatorDid: '',
+ creatorHandle: '',
+}, {
+ feedDescriptor: `feedgen|${SYU_IS_FEED_URI}`,
+ displayName: 'Feeds',
+ id: SYU_IS_FEED_URI,
+ uri: SYU_IS_FEED_URI,
+ type: 'feed',
+ savedFeed: {
+ type: 'feed',
+ value: SYU_IS_FEED_URI,
+ pinned: true,
+ },
+ pinned: true,
+ route: { href: '/', name: 'Home', params: {} },
+ cid: '',
+ avatar: '',
+ creatorDid: '',
+ creatorHandle: '',
+}]
+
type Props = NativeStackScreenProps<HomeTabNavigatorParams, 'Home' | 'Start'>
@@ -105,7 +129,9 @@ index e058e2883..0f583c915 100644
+ const {data: pinnedFeedInfos} = usePinnedFeedsInfos()
+
+ const safePreferences = preferences || { feedViewPrefs: { lab_mergeFeedEnabled: false }, savedFeeds: [] } as any
+ const safePinnedFeedInfos = DEFAULT_PINNED_FEEDS
+ const safePinnedFeedInfos = !currentAccount
+ ? DEFAULT_PINNED_FEEDS.filter(f => f.feedDescriptor !== 'following')
+ : DEFAULT_PINNED_FEEDS
React.useEffect(() => {
if (isWeb && !currentAccount) {
@@ -189,8 +215,7 @@ index e058e2883..0f583c915 100644
- const maybeSelectedFeed: FeedDescriptor | undefined = allFeeds[selectedIndex]
+ const maybeSelectedFeed = allFeeds[selectedIndex]
const requestNotificationsPermission = useRequestNotificationsPermission()
-
+
useSetTitle(pinnedFeedInfos[selectedIndex]?.displayName)
useOTAUpdates()
-
@@ -208,7 +233,7 @@ index e058e2883..0f583c915 100644
if (selectedIndex !== lastPagerReportedIndexRef.current) {
lastPagerReportedIndexRef.current = selectedIndex
pagerRef.current?.setPage(selectedIndex)
@@ -138,205 +90,43 @@ function HomeScreenReady({
@@ -138,205 +117,43 @@ function HomeScreenReady({
const {hasSession} = useSession()
const setMinimalShellMode = useSetMinimalShellMode()
@@ -217,7 +242,8 @@ index e058e2883..0f583c915 100644
- setMinimalShellMode(false)
- }, [setMinimalShellMode]),
- )
-
+ useFocusEffect(React.useCallback(() => { setMinimalShellMode(false) }, [setMinimalShellMode]))
- useFocusEffect(
- useNonReactiveCallback(() => {
- if (maybeSelectedFeed) {
@@ -235,7 +261,13 @@ index e058e2883..0f583c915 100644
- (index: number) => {
- setMinimalShellMode(false)
- const maybeFeed = allFeeds[index]
-
+ const onPageSelected = React.useCallback((index) => {
+ setMinimalShellMode(false)
+ const maybeFeed = allFeeds[index]
+ lastPagerReportedIndexRef.current = index
+ setSelectedFeed(maybeFeed)
+ }, [setSelectedFeed, setMinimalShellMode, allFeeds])
- // 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
@@ -265,15 +297,6 @@ index e058e2883..0f583c915 100644
- },
- [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'
@@ -281,7 +304,10 @@ index e058e2883..0f583c915 100644
+ }, [setMinimalShellMode])
const [demoMode] = useDemoMode()
-
+ const renderTabBar = React.useCallback((props) => {
+ return <HomeHeader key="FEEDS_TAB_BAR" {...props} testID="homeScreenFeedTabs" onPressSelected={onPressSelected} feeds={pinnedFeedInfos} />
+ }, [onPressSelected, pinnedFeedInfos])
- const renderTabBar = React.useCallback(
- (props: RenderTabBarFnProps) => {
- if (demoMode) {
@@ -312,11 +338,16 @@ index e058e2883..0f583c915 100644
- const renderFollowingEmptyState = React.useCallback(() => {
- return <FollowingEmptyState />
- }, [])
-
+ const renderFollowingEmptyState = React.useCallback(() => <FollowingEmptyState />, [])
+ const renderCustomFeedEmptyState = React.useCallback(() => <CustomFeedEmptyState />, [])
- const renderCustomFeedEmptyState = React.useCallback(() => {
- return <CustomFeedEmptyState />
- }, [])
-
+ const homeFeedParams = React.useMemo(() => ({
+ mergeFeedEnabled: false, mergeFeedSources: []
+ }), [preferences])
- const homeFeedParams = React.useMemo<FeedParams>(() => {
- return {
- mergeFeedEnabled: Boolean(preferences.feedViewPrefs.lab_mergeFeedEnabled),
@@ -368,17 +399,6 @@ index e058e2883..0f583c915 100644
- 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) => {
@@ -447,7 +467,7 @@ index e058e2883..0f583c915 100644
-})
+const styles = StyleSheet.create({ loading: { height: '100%', alignContent: 'center', justifyContent: 'center', paddingBottom: 100 } })
diff --git a/src/view/screens/PrivacyPolicy.tsx b/src/view/screens/PrivacyPolicy.tsx
index a89eaadc4..228af4966 100644
index a89eaadc4..1da393f03 100644
--- a/src/view/screens/PrivacyPolicy.tsx
+++ b/src/view/screens/PrivacyPolicy.tsx
@@ -1,52 +1,13 @@
@@ -509,7 +529,7 @@ index a89eaadc4..228af4966 100644
)
}
diff --git a/src/view/screens/TermsOfService.tsx b/src/view/screens/TermsOfService.tsx
index d843c713c..c0b34c886 100644
index d843c713c..b81767bd5 100644
--- a/src/view/screens/TermsOfService.tsx
+++ b/src/view/screens/TermsOfService.tsx
@@ -1,50 +1,13 @@

View File

@@ -1,8 +1,8 @@
diff --git a/bskyweb/cmd/bskyweb/server.go b/bskyweb/cmd/bskyweb/server.go
index ec5261dee..c670cf75a 100644
index 790f211ee..ec05a8bcd 100644
--- a/bskyweb/cmd/bskyweb/server.go
+++ b/bskyweb/cmd/bskyweb/server.go
@@ -302,6 +302,12 @@ func serve(cctx *cli.Context) error {
@@ -317,6 +317,12 @@ func serve(cctx *cli.Context) error {
e.GET("/support/tos", server.WebGeneric)
e.GET("/support/community-guidelines", server.WebGeneric)
e.GET("/support/copyright", server.WebGeneric)
@@ -15,9 +15,9 @@ index ec5261dee..c670cf75a 100644
e.GET("/intent/compose", server.WebGeneric)
e.GET("/intent/verify-email", server.WebGeneric)
e.GET("/intent/age-assurance", server.WebGeneric)
@@ -755,3 +761,33 @@ func (srv *Server) WebIpCC(c echo.Context) error {
}
return c.JSON(200, outResponse)
@@ -825,3 +831,33 @@ func (srv *Server) serveSitemapRequest(c echo.Context, url, sitemapType string)
return nil
}
+
+// Handler for About TOS page (syu.is specific)
@@ -51,7 +51,7 @@ index ec5261dee..c670cf75a 100644
+}
diff --git a/bskyweb/templates/about-app.html b/bskyweb/templates/about-app.html
new file mode 100644
index 000000000..000000002
index 000000000..62a39a21d
--- /dev/null
+++ b/bskyweb/templates/about-app.html
@@ -0,0 +1,135 @@
@@ -152,26 +152,26 @@ index 000000000..000000002
+ <div class="link-row">
+ <span class="link-icon">GitHub</span>
+ <a href="https://github.com/syui" class="link-value" target="_blank">github.com/syui</a>
+ <span class="link-arrow"></span>
+ <span class="link-arrow">&rarr;</span>
+ </div>
+ <div class="link-row">
+ <span class="link-icon">ATProto</span>
+ <a href="https://syu.is/syui" class="link-value" target="_blank">syu.is/syui</a>
+ <span class="link-arrow"></span>
+ <span class="link-arrow">&rarr;</span>
+ </div>
+ </div>
+
+ <div class="section">
+ <div class="section-title">Bitcoin</div>
+ <div class="bitcoin-row">
+ <span class="bitcoin-label"></span>
+ <span class="bitcoin-label">&#8383;</span>
+ <span class="bitcoin-address" id="btc-address">3BqHXxraZyBapyNpJmniJDh9zqzuB8aoRr</span>
+ <span class="copy-btn" onclick="copyBTC()">copy</span>
+ </div>
+ </div>
+
+ <div class="footer">
+ <p class="copyright">© syui</p>
+ <p class="copyright">&copy; syui</p>
+ </div>
+
+ <script>
@@ -190,84 +190,12 @@ index 000000000..000000002
+ </script>
+</body>
+</html>
diff --git a/bskyweb/templates/about-license.html b/bskyweb/templates/about-license.html
new file mode 100644
index 000000000..000000003
--- /dev/null
+++ b/bskyweb/templates/about-license.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html lang="ja">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
+ <title>License - syu.is</title>
+ <link rel="icon" type="image/png" href="{{ staticCDNHost }}/static/favicon.png">
+ <style>
+ * { box-sizing: border-box; margin: 0; padding: 0; }
+ body {
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
+ line-height: 1.6;
+ color: #1a1a1a;
+ background: #fff;
+ padding: 20px;
+ max-width: 800px;
+ margin: 0 auto;
+ }
+ @media (prefers-color-scheme: dark) {
+ body { background: #000; color: #e0e0e0; }
+ a { color: #6bb3ff; }
+ h1, h2, h3 { color: #fff; }
+ }
+ h1 { font-size: 28px; margin-bottom: 24px; padding-bottom: 12px; border-bottom: 1px solid #ddd; }
+ h2 { font-size: 20px; margin: 24px 0 12px; }
+ p { margin-bottom: 16px; }
+ ul { margin: 0 0 16px 24px; }
+ li { margin-bottom: 8px; }
+ a { color: #0066cc; text-decoration: none; }
+ a:hover { text-decoration: underline; }
+ .header { margin-bottom: 32px; }
+ .back-link { display: inline-block; margin-bottom: 16px; font-size: 14px; }
+ .footer { margin-top: 40px; padding-top: 20px; border-top: 1px solid #ddd; font-size: 14px; color: #666; }
+ pre { background: #f5f5f5; padding: 16px; border-radius: 8px; overflow-x: auto; font-size: 13px; }
+ @media (prefers-color-scheme: dark) { pre { background: #1a1a1a; } }
+ </style>
+</head>
+<body>
+ <div class="header">
+ <a href="/" class="back-link">&larr; Back to syu.is</a>
+ <h1>License</h1>
+ </div>
+
+ <h2>Aiat (iOS/Android App)</h2>
+ <p>This application is based on the Bluesky Social App, which is open source software.</p>
+
+ <h2>Open Source Licenses</h2>
+ <p>This app uses the following open source software:</p>
+
+ <h3>Bluesky Social App</h3>
+ <p>Licensed under the MIT License</p>
+ <p><a href="https://github.com/bluesky-social/social-app" target="_blank">https://github.com/bluesky-social/social-app</a></p>
+
+ <h3>AT Protocol</h3>
+ <p>Licensed under the MIT License / Apache 2.0</p>
+ <p><a href="https://github.com/bluesky-social/atproto" target="_blank">https://github.com/bluesky-social/atproto</a></p>
+
+ <h2>Third Party Libraries</h2>
+ <p>This application includes various third-party libraries, each with their own licenses. For a complete list, please see the application's source code repository.</p>
+
+ <div class="footer">
+ <p>Last updated: 2025</p>
+ <p>&copy; syu.is</p>
+ </div>
+</body>
+</html>
diff --git a/bskyweb/templates/about-help.html b/bskyweb/templates/about-help.html
new file mode 100644
index 000000000..d37db25c5
index 000000000..89f40e414
--- /dev/null
+++ b/bskyweb/templates/about-help.html
@@ -0,0 +1,91 @@
@@ -0,0 +1,100 @@
+<!DOCTYPE html>
+<html lang="ja">
+<head>
@@ -368,12 +296,84 @@ index 000000000..d37db25c5
+ </div>
+</body>
+</html>
diff --git a/bskyweb/templates/about-license.html b/bskyweb/templates/about-license.html
new file mode 100644
index 000000000..02fe64696
--- /dev/null
+++ b/bskyweb/templates/about-license.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html lang="ja">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
+ <title>License - syu.is</title>
+ <link rel="icon" type="image/png" href="{{ staticCDNHost }}/static/favicon.png">
+ <style>
+ * { box-sizing: border-box; margin: 0; padding: 0; }
+ body {
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
+ line-height: 1.6;
+ color: #1a1a1a;
+ background: #fff;
+ padding: 20px;
+ max-width: 800px;
+ margin: 0 auto;
+ }
+ @media (prefers-color-scheme: dark) {
+ body { background: #000; color: #e0e0e0; }
+ a { color: #6bb3ff; }
+ h1, h2, h3 { color: #fff; }
+ }
+ h1 { font-size: 28px; margin-bottom: 24px; padding-bottom: 12px; border-bottom: 1px solid #ddd; }
+ h2 { font-size: 20px; margin: 24px 0 12px; }
+ p { margin-bottom: 16px; }
+ ul { margin: 0 0 16px 24px; }
+ li { margin-bottom: 8px; }
+ a { color: #0066cc; text-decoration: none; }
+ a:hover { text-decoration: underline; }
+ .header { margin-bottom: 32px; }
+ .back-link { display: inline-block; margin-bottom: 16px; font-size: 14px; }
+ .footer { margin-top: 40px; padding-top: 20px; border-top: 1px solid #ddd; font-size: 14px; color: #666; }
+ pre { background: #f5f5f5; padding: 16px; border-radius: 8px; overflow-x: auto; font-size: 13px; }
+ @media (prefers-color-scheme: dark) { pre { background: #1a1a1a; } }
+ </style>
+</head>
+<body>
+ <div class="header">
+ <a href="/" class="back-link">&larr; Back to syu.is</a>
+ <h1>License</h1>
+ </div>
+
+ <h2>Aiat (iOS/Android App)</h2>
+ <p>This application is based on the Bluesky Social App, which is open source software.</p>
+
+ <h2>Open Source Licenses</h2>
+ <p>This app uses the following open source software:</p>
+
+ <h3>Bluesky Social App</h3>
+ <p>Licensed under the MIT License</p>
+ <p><a href="https://github.com/bluesky-social/social-app" target="_blank">https://github.com/bluesky-social/social-app</a></p>
+
+ <h3>AT Protocol</h3>
+ <p>Licensed under the MIT License / Apache 2.0</p>
+ <p><a href="https://github.com/bluesky-social/atproto" target="_blank">https://github.com/bluesky-social/atproto</a></p>
+
+ <h2>Third Party Libraries</h2>
+ <p>This application includes various third-party libraries, each with their own licenses. For a complete list, please see the application's source code repository.</p>
+
+ <div class="footer">
+ <p>Last updated: 2025</p>
+ <p>&copy; syu.is</p>
+ </div>
+</body>
+</html>
diff --git a/bskyweb/templates/about-privacy.html b/bskyweb/templates/about-privacy.html
new file mode 100644
index 000000000..14a1168ad
--- /dev/null
+++ b/bskyweb/templates/about-privacy.html
@@ -0,0 +1,83 @@
@@ -0,0 +1,92 @@
+<!DOCTYPE html>
+<html lang="ja">
+<head>
@@ -471,7 +471,7 @@ new file mode 100644
index 000000000..db5d82f5c
--- /dev/null
+++ b/bskyweb/templates/about-tos.html
@@ -0,0 +1,76 @@
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<html lang="ja">
+<head>

View File

@@ -1,51 +0,0 @@
diff --git a/src/view/com/auth/SplashScreen.tsx b/src/view/com/auth/SplashScreen.tsx
--- a/src/view/com/auth/SplashScreen.tsx
+++ b/src/view/com/auth/SplashScreen.tsx
@@ -46,23 +46,6 @@ export const SplashScreen = ({
<View
testID="signinOrCreateAccount"
style={[a.px_xl, a.gap_md, a.pb_2xl]}>
- <Button
- testID="createAccountButton"
- onPress={() => {
- onPressCreateAccount()
- playHaptic('Light')
- }}
- label={_(msg`Create new account`)}
- accessibilityHint={_(
- msg`Opens flow to create a new Bluesky account`,
- )}
- size="large"
- variant="solid"
- color="primary">
- <ButtonText>
- <Trans>Create account</Trans>
- </ButtonText>
- </Button>
<Button
testID="signInButton"
onPress={() => {
diff --git a/src/view/com/auth/SplashScreen.web.tsx b/src/view/com/auth/SplashScreen.web.tsx
--- a/src/view/com/auth/SplashScreen.web.tsx
+++ b/src/view/com/auth/SplashScreen.web.tsx
@@ -97,20 +97,6 @@ export const SplashScreen = ({
<View
testID="signinOrCreateAccount"
style={[a.w_full, a.px_xl, a.gap_md, a.pb_2xl, {maxWidth: 320}]}>
- <Button
- testID="createAccountButton"
- onPress={onPressCreateAccount}
- label={_(msg`Create new account`)}
- accessibilityHint={_(
- msg`Opens flow to create a new Bluesky account`,
- )}
- size="large"
- variant="solid"
- color="primary">
- <ButtonText>
- <Trans>Create account</Trans>
- </ButtonText>
- </Button>
<Button
testID="signInButton"
onPress={onPressSignin}

View File

@@ -11,7 +11,7 @@ index 123456789..987654321 100644
const showLikesTab = isMe
const feedGenCount = profile.associated?.feedgens || 0
- const showFeedsTab = isMe || feedGenCount > 0
+ const showFeedsTab = false
+ const showFeedsTab = feedGenCount > 0
const starterPackCount = profile.associated?.starterPacks || 0
- const showStarterPacksTab = isMe || starterPackCount > 0
+ const showStarterPacksTab = false

View File

@@ -1,19 +0,0 @@
diff --git a/src/view/com/home/HomeHeader.tsx b/src/view/com/home/HomeHeader.tsx
index 4a2cf881f..0dd8547f7 100644
--- a/src/view/com/home/HomeHeader.tsx
+++ b/src/view/com/home/HomeHeader.tsx
@@ -28,12 +28,8 @@ export function HomeHeader(
}, [feeds, hasSession])
const items = React.useMemo(() => {
- const pinnedNames = feeds.map(f => f.displayName)
- if (!hasPinnedCustom) {
- return pinnedNames.concat('Feeds ✨')
- }
- return pinnedNames
- }, [hasPinnedCustom, feeds])
+ return ['Following']
+ }, [])
const onPressFeedsLink = React.useCallback(() => {
navigation.navigate('Feeds')

View File

@@ -0,0 +1,28 @@
diff --git a/src/view/com/home/HomeHeader.tsx b/src/view/com/home/HomeHeader.tsx
--- a/src/view/com/home/HomeHeader.tsx
+++ b/src/view/com/home/HomeHeader.tsx
@@ -3,7 +3,6 @@ import {useNavigation} from '@react-navigation/native'
import {type NavigationProp} from '#/lib/routes/types'
import {type FeedSourceInfo} from '#/state/queries/feed'
-import {useSession} from '#/state/session'
import {type RenderTabBarFnProps} from '#/view/com/pager/Pager'
import {TabBar} from '../pager/TabBar'
import {HomeHeaderLayout} from './HomeHeaderLayout'
@@ -16,17 +15,15 @@ export function HomeHeader(
) {
const {feeds, onSelect: onSelectProp} = props
- const {hasSession} = useSession()
const navigation = useNavigation<NavigationProp>()
const hasPinnedCustom = React.useMemo<boolean>(() => {
- if (!hasSession) return false
return feeds.some(tab => {
const isFollowing = tab.uri === 'following'
return !isFollowing
})
- }, [feeds, hasSession])
+ }, [feeds])
const items = React.useMemo(() => {
const pinnedNames = feeds.map(f => f.displayName)

310
ios/patching/AppInfo.tsx Normal file
View File

@@ -0,0 +1,310 @@
import React, {useState} from 'react'
import {
View,
ScrollView,
StyleSheet,
Pressable,
Image,
} from 'react-native'
import * as Clipboard from 'expo-clipboard'
import * as WebBrowser from 'expo-web-browser'
import {Trans} from '@lingui/macro'
import * as Layout from '#/components/Layout'
import {Text} from '#/components/Typography'
import {useSetTitle} from '#/lib/hooks/useSetTitle'
import {atoms as a, useTheme} from '#/alf'
const APP_VERSION = '1.111.0'
const APP_NAME = 'Aiat'
const BITCOIN_ADDRESS = '3BqHXxraZyBapyNpJmniJDh9zqzuB8aoRr'
export function AppInfoScreen() {
useSetTitle('App Info')
const t = useTheme()
const [copied, setCopied] = useState(false)
const copyToClipboard = async (text: string) => {
try {
await Clipboard.setStringAsync(text)
setCopied(true)
setTimeout(() => setCopied(false), 2000)
} catch (e) {
console.log('Clipboard not available')
}
}
const openUrl = (url: string) => {
WebBrowser.openBrowserAsync(url)
}
return (
<Layout.Screen>
<Layout.Header.Outer>
<Layout.Header.BackButton />
<Layout.Header.Content>
<Layout.Header.TitleText>
<Trans>App Info</Trans>
</Layout.Header.TitleText>
</Layout.Header.Content>
<Layout.Header.Slot />
</Layout.Header.Outer>
<Layout.Content>
<ScrollView
style={[a.flex_1]}
contentContainerStyle={[a.p_lg, a.pt_xl, a.pb_5xl]}>
{/* App Header */}
<View style={styles.appHeader}>
<View style={[styles.appIconContainer, t.atoms.bg_contrast_25]}>
<Image
source={require('../../../assets/logo.png')}
style={styles.appIcon}
resizeMode="cover"
/>
</View>
<Text style={[styles.appName, t.atoms.text]}>
{APP_NAME}
</Text>
<Text style={[styles.appVersion, t.atoms.text_contrast_medium]}>
v{APP_VERSION}
</Text>
</View>
{/* Description Section */}
<View style={[styles.section, t.atoms.bg_contrast_25]}>
<Text style={[styles.description, t.atoms.text]}>
{APP_NAME} is a social networking application based on AT Protocol.
Connect with your community on syu.is.
</Text>
</View>
{/* App Information Section */}
<View style={[styles.section, t.atoms.bg_contrast_25]}>
<Text style={[styles.sectionTitle, t.atoms.text_contrast_medium]}>
App Information
</Text>
<View style={styles.infoGrid}>
<View style={[styles.infoItem, t.atoms.bg_contrast_50]}>
<Text style={[styles.infoLabel, t.atoms.text_contrast_medium]}>
Version
</Text>
<Text style={[styles.infoValue, t.atoms.text]}>
{APP_VERSION}
</Text>
</View>
<View style={[styles.infoItem, t.atoms.bg_contrast_50]}>
<Text style={[styles.infoLabel, t.atoms.text_contrast_medium]}>
Category
</Text>
<Text style={[styles.infoValue, t.atoms.text]}>
Social
</Text>
</View>
<View style={[styles.infoItem, t.atoms.bg_contrast_50]}>
<Text style={[styles.infoLabel, t.atoms.text_contrast_medium]}>
Supported OS
</Text>
<Text style={[styles.infoValue, t.atoms.text]}>
iOS 26.0+
</Text>
</View>
<View style={[styles.infoItem, t.atoms.bg_contrast_50]}>
<Text style={[styles.infoLabel, t.atoms.text_contrast_medium]}>
Price
</Text>
<Text style={[styles.infoValue, t.atoms.text]}>
Free
</Text>
</View>
</View>
</View>
{/* Developer Section */}
<View style={[styles.section, t.atoms.bg_contrast_25]}>
<Text style={[styles.sectionTitle, t.atoms.text_contrast_medium]}>
Developer
</Text>
<View style={styles.developerCard}>
<Text style={[styles.developerName, t.atoms.text]}>syui</Text>
</View>
<Pressable
onPress={() => openUrl('https://github.com/syui')}
style={[styles.linkRow, t.atoms.border_contrast_low]}>
<Text style={[styles.linkIcon, t.atoms.text_contrast_medium]}>
GitHub
</Text>
<Text style={[styles.linkValue, {color: '#0084ff'}]}>
github.com/syui
</Text>
<Text style={[styles.linkArrow, t.atoms.text_contrast_low]}></Text>
</Pressable>
<Pressable
onPress={() => openUrl('https://syu.is/syui')}
style={[styles.linkRow, t.atoms.border_contrast_low]}>
<Text style={[styles.linkIcon, t.atoms.text_contrast_medium]}>
ATProto
</Text>
<Text style={[styles.linkValue, {color: '#0084ff'}]}>
syu.is/syui
</Text>
<Text style={[styles.linkArrow, t.atoms.text_contrast_low]}></Text>
</Pressable>
</View>
{/* Bitcoin Section */}
<View style={[styles.section, t.atoms.bg_contrast_25]}>
<Text style={[styles.sectionTitle, t.atoms.text_contrast_medium]}>
Bitcoin
</Text>
<Pressable
onPress={() => copyToClipboard(BITCOIN_ADDRESS)}
style={styles.bitcoinRow}>
<Text style={styles.bitcoinLabel}></Text>
<Text style={[styles.bitcoinAddress, t.atoms.text_contrast_medium]}>
{BITCOIN_ADDRESS}
</Text>
<Text style={[styles.copyHint, copied && styles.copiedHint]}>
{copied ? 'copied!' : 'copy'}
</Text>
</Pressable>
</View>
{/* Copyright */}
<View style={styles.copyright}>
<Text style={[styles.copyrightText, t.atoms.text_contrast_low]}>
© syui
</Text>
</View>
</ScrollView>
</Layout.Content>
</Layout.Screen>
)
}
const styles = StyleSheet.create({
appHeader: {
alignItems: 'center',
marginBottom: 24,
},
appIconContainer: {
width: 80,
height: 80,
borderRadius: 18,
overflow: 'hidden',
marginBottom: 12,
},
appIcon: {
width: '100%',
height: '100%',
},
appName: {
fontSize: 24,
fontWeight: 'bold',
marginBottom: 4,
},
appVersion: {
fontSize: 14,
},
section: {
marginBottom: 16,
borderRadius: 16,
padding: 16,
},
sectionTitle: {
fontSize: 13,
fontWeight: '600',
textTransform: 'uppercase',
letterSpacing: 0.5,
marginBottom: 12,
},
description: {
fontSize: 15,
lineHeight: 22,
},
infoGrid: {
flexDirection: 'row',
flexWrap: 'wrap',
gap: 8,
},
infoItem: {
flex: 1,
minWidth: '45%',
alignItems: 'center',
borderRadius: 12,
padding: 12,
},
infoLabel: {
fontSize: 11,
textTransform: 'uppercase',
letterSpacing: 0.5,
marginBottom: 4,
},
infoValue: {
fontSize: 16,
fontWeight: '600',
textAlign: 'center',
},
developerCard: {
marginBottom: 12,
},
developerName: {
fontSize: 18,
fontWeight: '600',
},
linkRow: {
flexDirection: 'row',
alignItems: 'center',
paddingVertical: 12,
borderTopWidth: 1,
},
linkIcon: {
fontSize: 14,
fontWeight: '600',
width: 70,
},
linkValue: {
flex: 1,
fontSize: 14,
},
linkArrow: {
fontSize: 16,
},
bitcoinRow: {
flexDirection: 'row',
alignItems: 'center',
backgroundColor: 'rgba(247, 147, 26, 0.08)',
borderRadius: 12,
padding: 14,
gap: 10,
},
bitcoinLabel: {
fontSize: 18,
fontWeight: '600',
color: '#f7931a',
},
bitcoinAddress: {
flex: 1,
fontSize: 11,
fontFamily: 'monospace',
},
copyHint: {
fontSize: 12,
color: '#999999',
minWidth: 50,
textAlign: 'right',
},
copiedHint: {
color: '#4CAF50',
fontWeight: '600',
},
copyright: {
alignItems: 'center',
marginTop: 20,
marginBottom: 20,
},
copyrightText: {
fontSize: 12,
},
})