about summary refs log tree commit diff
path: root/src/screens/Search/components/SearchHistory.tsx
diff options
context:
space:
mode:
authorSamuel Newman <mozzius@protonmail.com>2025-04-03 03:21:15 +0300
committerGitHub <noreply@github.com>2025-04-02 17:21:15 -0700
commit87da619aaa92e0ec762e68c13b24e58a25da10a8 (patch)
tree4da902d3ca43a226f6da8e5c090ab33c2df3297a /src/screens/Search/components/SearchHistory.tsx
parent8d1f97b5ffac5d86762f1d4e9384ff3097acbc52 (diff)
downloadvoidsky-87da619aaa92e0ec762e68c13b24e58a25da10a8.tar.zst
[Explore] Base (#8053)
* migrate to #/screens

* rm unneeded import

* block drawer gesture on recent profiles

* rm recommendations (#8056)

* [Explore] Disable Trending videos (#8054)

* remove giant header

* disable

* [Explore] Dynamic module ordering (#8066)

* Dynamic module ordering

* [Explore] New headers, metrics (#8067)

* new sticky headers

* improve spacing between modules

* view metric on modules

* update metrics names

* [Explore] Suggested accounts module (#8072)

* use modern profile card, update load more

* add tab bar

* tabbed suggested accounts

* [Explore] Discover feeds module (#8073)

* cap number of feeds to 3

* change feed pin button

* Apply suggestions from code review

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* restore statsig to log events

* filter out followed profiles, make suer enough are loaded (#8090)

* [Explore] Trending topics (#8055)

* redesigned trending topics

* rm borders on web

* get post count / age / ranking from api

* spacing tweaks

* fetch more topics then slice

* use api data for avis/category

* rm top border

* Integrate new SDK, part out components

* Clean up

* Use status field

* Bump SDK

* Send up interests and langs

---------

Co-authored-by: Eric Bailey <git@esb.lol>

* Clean up module spacing and borders

(cherry picked from commit 63d19b6c2d67e226e0e14709b1047a1f88b3ce1c)
(cherry picked from commit 62d7d394ab1dc31b40b9c2cf59075adbf94737a1)

* Switch back border ordering

(cherry picked from commit 34e3789f8b410132c1390df3c2bb8257630ebdd9)

* [Explore] Starter Packs (#8095)

* Temp WIP

(cherry picked from commit 43b5d7b1e64b3adb1ed162262d0310e0bf026c18)

* New SP card

* Load state

* Revert change

* Cleanup

* Interests and caching

* Count total

* Format

* Caching

* [Explore] Feed previews module (#8075)

* wip new hook

* get fetching working, maybe

* get feed previews rendering!

* fix header height

* working pin button

* extract out FeedLink

* add loader

* only make preview:header sticky

* Fix headers

* Header tweaks

* Fix moderation filter

* Fix threading

---------

Co-authored-by: Eric Bailey <git@esb.lol>

* Space it out

* Fix query key

* Mock new endpoint, filter saved feeds

* Make sure we're pinning, lower cache time

* add news category

* Remove log

* Improve suggested accounts load state

* Integrate new app view endpoint

* fragment

* Update src/screens/Search/modules/ExploreTrendingTopics.tsx

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* Update src/screens/Search/modules/ExploreTrendingTopics.tsx

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>

* lint

* maybe fix this

---------

Co-authored-by: surfdude29 <149612116+surfdude29@users.noreply.github.com>
Co-authored-by: Eric Bailey <git@esb.lol>
Co-authored-by: Hailey <me@haileyok.com>
Diffstat (limited to 'src/screens/Search/components/SearchHistory.tsx')
-rw-r--r--src/screens/Search/components/SearchHistory.tsx169
1 files changed, 169 insertions, 0 deletions
diff --git a/src/screens/Search/components/SearchHistory.tsx b/src/screens/Search/components/SearchHistory.tsx
new file mode 100644
index 000000000..5e62f2cd0
--- /dev/null
+++ b/src/screens/Search/components/SearchHistory.tsx
@@ -0,0 +1,169 @@
+import {Pressable, ScrollView, StyleSheet, View} from 'react-native'
+import {msg, Trans} from '@lingui/macro'
+import {useLingui} from '@lingui/react'
+
+import {createHitslop, HITSLOP_10} from '#/lib/constants'
+import {makeProfileLink} from '#/lib/routes/links'
+import {sanitizeDisplayName} from '#/lib/strings/display-names'
+import {Link} from '#/view/com/util/Link'
+import {UserAvatar} from '#/view/com/util/UserAvatar'
+import {BlockDrawerGesture} from '#/view/shell/BlockDrawerGesture'
+import {atoms as a, tokens, useBreakpoints, useTheme} from '#/alf'
+import {Button, ButtonIcon} from '#/components/Button'
+import {TimesLarge_Stroke2_Corner0_Rounded as XIcon} from '#/components/icons/Times'
+import * as Layout from '#/components/Layout'
+import {Text} from '#/components/Typography'
+import type * as bsky from '#/types/bsky'
+
+export function SearchHistory({
+  searchHistory,
+  selectedProfiles,
+  onItemClick,
+  onProfileClick,
+  onRemoveItemClick,
+  onRemoveProfileClick,
+}: {
+  searchHistory: string[]
+  selectedProfiles: bsky.profile.AnyProfileView[]
+  onItemClick: (item: string) => void
+  onProfileClick: (profile: bsky.profile.AnyProfileView) => void
+  onRemoveItemClick: (item: string) => void
+  onRemoveProfileClick: (profile: bsky.profile.AnyProfileView) => void
+}) {
+  const {gtMobile} = useBreakpoints()
+  const t = useTheme()
+  const {_} = useLingui()
+
+  return (
+    <Layout.Content
+      keyboardDismissMode="interactive"
+      keyboardShouldPersistTaps="handled">
+      <View style={[a.w_full, a.px_md]}>
+        {(searchHistory.length > 0 || selectedProfiles.length > 0) && (
+          <Text style={[a.text_md, a.font_bold, a.p_md]}>
+            <Trans>Recent Searches</Trans>
+          </Text>
+        )}
+        {selectedProfiles.length > 0 && (
+          <View
+            style={[
+              styles.selectedProfilesContainer,
+              !gtMobile && styles.selectedProfilesContainerMobile,
+            ]}>
+            <BlockDrawerGesture>
+              <ScrollView
+                horizontal
+                keyboardShouldPersistTaps="handled"
+                style={[
+                  a.flex_row,
+                  a.flex_nowrap,
+                  {marginHorizontal: tokens.space._2xl * -1},
+                ]}
+                contentContainerStyle={[a.px_2xl, a.border_0]}>
+                {selectedProfiles.slice(0, 5).map((profile, index) => (
+                  <View
+                    key={index}
+                    style={[
+                      styles.profileItem,
+                      !gtMobile && styles.profileItemMobile,
+                    ]}>
+                    <Link
+                      href={makeProfileLink(profile)}
+                      title={profile.handle}
+                      asAnchor
+                      anchorNoUnderline
+                      onBeforePress={() => onProfileClick(profile)}
+                      style={[a.align_center, a.w_full]}>
+                      <UserAvatar
+                        avatar={profile.avatar}
+                        type={profile.associated?.labeler ? 'labeler' : 'user'}
+                        size={60}
+                      />
+                      <Text
+                        emoji
+                        style={[a.text_xs, a.text_center, styles.profileName]}
+                        numberOfLines={1}>
+                        {sanitizeDisplayName(
+                          profile.displayName || profile.handle,
+                        )}
+                      </Text>
+                    </Link>
+                    <Pressable
+                      accessibilityRole="button"
+                      accessibilityLabel={_(msg`Remove profile`)}
+                      accessibilityHint={_(
+                        msg`Removes profile from search history`,
+                      )}
+                      onPress={() => onRemoveProfileClick(profile)}
+                      hitSlop={createHitslop(6)}
+                      style={styles.profileRemoveBtn}>
+                      <XIcon size="xs" style={t.atoms.text_contrast_low} />
+                    </Pressable>
+                  </View>
+                ))}
+              </ScrollView>
+            </BlockDrawerGesture>
+          </View>
+        )}
+        {searchHistory.length > 0 && (
+          <View style={[a.pl_md, a.pr_xs, a.mt_md]}>
+            {searchHistory.slice(0, 5).map((historyItem, index) => (
+              <View key={index} style={[a.flex_row, a.align_center, a.mt_xs]}>
+                <Pressable
+                  accessibilityRole="button"
+                  onPress={() => onItemClick(historyItem)}
+                  hitSlop={HITSLOP_10}
+                  style={[a.flex_1, a.py_md]}>
+                  <Text style={[a.text_md]}>{historyItem}</Text>
+                </Pressable>
+                <Button
+                  label={_(msg`Remove ${historyItem}`)}
+                  onPress={() => onRemoveItemClick(historyItem)}
+                  size="small"
+                  variant="ghost"
+                  color="secondary"
+                  shape="round">
+                  <ButtonIcon icon={XIcon} />
+                </Button>
+              </View>
+            ))}
+          </View>
+        )}
+      </View>
+    </Layout.Content>
+  )
+}
+
+const styles = StyleSheet.create({
+  selectedProfilesContainer: {
+    marginTop: 10,
+    paddingHorizontal: 12,
+    height: 80,
+  },
+  selectedProfilesContainerMobile: {
+    height: 100,
+  },
+  profileItem: {
+    alignItems: 'center',
+    marginRight: 15,
+    width: 78,
+  },
+  profileItemMobile: {
+    width: 70,
+  },
+  profileName: {
+    width: 78,
+    marginTop: 6,
+  },
+  profileRemoveBtn: {
+    position: 'absolute',
+    top: 0,
+    right: 5,
+    backgroundColor: 'white',
+    borderRadius: 10,
+    width: 18,
+    height: 18,
+    alignItems: 'center',
+    justifyContent: 'center',
+  },
+})