Merge branch 'main' into starter-packs
This commit is contained in:
@@ -34,6 +34,9 @@ jobs:
|
|||||||
node-version-file: .nvmrc
|
node-version-file: .nvmrc
|
||||||
cache: yarn
|
cache: yarn
|
||||||
|
|
||||||
|
- name: 🪛 Setup jq
|
||||||
|
uses: dcarbone/install-jq-action@v2
|
||||||
|
|
||||||
- name: 🔨 Setup EAS
|
- name: 🔨 Setup EAS
|
||||||
uses: expo/expo-github-action@v8
|
uses: expo/expo-github-action@v8
|
||||||
with:
|
with:
|
||||||
@@ -96,13 +99,17 @@ jobs:
|
|||||||
name: build-${{ steps.timestamp.outputs.time }}.apk
|
name: build-${{ steps.timestamp.outputs.time }}.apk
|
||||||
path: build.apk
|
path: build.apk
|
||||||
|
|
||||||
|
- name: 📚 Get version from package.json
|
||||||
|
id: get-build-info
|
||||||
|
run: bash scripts/setGitHubOutput.sh
|
||||||
|
|
||||||
- name: 🔔 Notify Slack of Production Build
|
- name: 🔔 Notify Slack of Production Build
|
||||||
if: ${{ inputs.profile == 'production' }}
|
if: ${{ inputs.profile == 'production' }}
|
||||||
uses: slackapi/slack-github-action@v1.25.0
|
uses: slackapi/slack-github-action@v1.25.0
|
||||||
with:
|
with:
|
||||||
payload: |
|
payload: |
|
||||||
{
|
{
|
||||||
"text": "Android build is ready for submission. This is a production build! Download the artifact here: ${{ steps.upload-artifact-production.outputs.artifact-url }}"
|
"text": "Android production build for Google Play Store submission is ready!\n```Artifact: ${{ steps.upload-artifact-production.outputs.artifact-url }}\nVersion Number: ${{ steps.get-build-info.outputs.PACKAGE_VERSION }}\nBuild Number: ${{ steps.get-build-info.outputs.BSKY_ANDROID_VERSION_CODE }}```"
|
||||||
}
|
}
|
||||||
env:
|
env:
|
||||||
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_CLIENT_ALERT_WEBHOOK }}
|
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_CLIENT_ALERT_WEBHOOK }}
|
||||||
@@ -140,7 +147,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
payload: |
|
payload: |
|
||||||
{
|
{
|
||||||
"text": "Android production APK build is ready for download. This is a production build, and you should add it to the GitHub release! Download the artifact here: ${{ steps.upload-artifact-production-apk.outputs.artifact-url }}"
|
"text": "Android production build for GitHub/Obtanium is ready!\n```Artifact: ${{ steps.upload-artifact-production-apk.outputs.artifact-url }}\nVersion Number: ${{ steps.get-build-info.outputs.PACKAGE_VERSION }}\nBuild Number: ${{ steps.get-build-info.outputs.BSKY_ANDROID_VERSION_CODE }}```"
|
||||||
}
|
}
|
||||||
env:
|
env:
|
||||||
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_CLIENT_ALERT_WEBHOOK }}
|
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_CLIENT_ALERT_WEBHOOK }}
|
||||||
|
|||||||
@@ -34,6 +34,9 @@ jobs:
|
|||||||
node-version-file: .nvmrc
|
node-version-file: .nvmrc
|
||||||
cache: yarn
|
cache: yarn
|
||||||
|
|
||||||
|
- name: 🪛 Setup jq
|
||||||
|
uses: dcarbone/install-jq-action@v2
|
||||||
|
|
||||||
- name: 🔨 Setup EAS
|
- name: 🔨 Setup EAS
|
||||||
uses: expo/expo-github-action@v8
|
uses: expo/expo-github-action@v8
|
||||||
with:
|
with:
|
||||||
@@ -81,6 +84,22 @@ jobs:
|
|||||||
- name: 🚀 Deploy
|
- name: 🚀 Deploy
|
||||||
run: eas submit -p ios --non-interactive --path build.ipa
|
run: eas submit -p ios --non-interactive --path build.ipa
|
||||||
|
|
||||||
|
- name: 📚 Get version from package.json
|
||||||
|
id: get-build-info
|
||||||
|
run: bash scripts/setGitHubOutput.sh
|
||||||
|
|
||||||
|
- name: 🔔 Notify Slack of Production Build
|
||||||
|
if: ${{ inputs.profile == 'production' }}
|
||||||
|
uses: slackapi/slack-github-action@v1.25.0
|
||||||
|
with:
|
||||||
|
payload: |
|
||||||
|
{
|
||||||
|
"text": "iOS production build for App Store submission is ready!\n```Artifact: Check TestFlight to know when it is available\nVersion Number: ${{ steps.get-build-info.outputs.PACKAGE_VERSION }}\nBuild Number: ${{ steps.get-build-info.outputs.BSKY_IOS_BUILD_NUMBER }}```"
|
||||||
|
}
|
||||||
|
env:
|
||||||
|
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_CLIENT_ALERT_WEBHOOK }}
|
||||||
|
SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK
|
||||||
|
|
||||||
- name: ⬇️ Restore Cache
|
- name: ⬇️ Restore Cache
|
||||||
id: get-base-commit
|
id: get-base-commit
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ appId: xyz.blueskyweb.app
|
|||||||
text: "1"
|
text: "1"
|
||||||
- tapOn:
|
- tapOn:
|
||||||
id: "repostBtn"
|
id: "repostBtn"
|
||||||
- tapOn: "Undo repost"
|
- tapOn: "Remove repost"
|
||||||
- assertNotVisible:
|
- assertNotVisible:
|
||||||
id: "repostCount"
|
id: "repostCount"
|
||||||
|
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
# Remove this test when the old onboarding is deprecated
|
|
||||||
appId: xyz.blueskyweb.app
|
|
||||||
---
|
|
||||||
- runScript:
|
|
||||||
file: ../setupServer.js
|
|
||||||
env:
|
|
||||||
SERVER_PATH: "?users"
|
|
||||||
- runFlow:
|
|
||||||
file: ../setupApp.yml
|
|
||||||
- tapOn:
|
|
||||||
id: "e2eSignInAlice"
|
|
||||||
- tapOn:
|
|
||||||
id: "e2eStartLongboarding"
|
|
||||||
- tapOn: "Continue to next step"
|
|
||||||
- tapOn: "Continue to the next step without following any accounts"
|
|
||||||
- tapOn: Show replies in Following feed
|
|
||||||
- tapOn: Show quote-posts in Following feed
|
|
||||||
- tapOn: Show re-posts in Following feed
|
|
||||||
- tapOn: Show replies in Following feed
|
|
||||||
- waitForAnimationToEnd
|
|
||||||
- tapOn: Continue to next step
|
|
||||||
- waitForAnimationToEnd
|
|
||||||
- tapOn: "Continue to the next step"
|
|
||||||
- waitForAnimationToEnd
|
|
||||||
- tapOn: Continue to next step
|
|
||||||
- waitForAnimationToEnd
|
|
||||||
- tapOn: Continue to next step
|
|
||||||
- waitForAnimationToEnd
|
|
||||||
- tapOn: "Complete onboarding and start using your account"
|
|
||||||
- waitForAnimationToEnd
|
|
||||||
- assertVisible: Following
|
|
||||||
+22
-8
@@ -14,15 +14,20 @@ diff results in incompatible native changes, a new client build will automatical
|
|||||||
|
|
||||||
### Prerequisites
|
### Prerequisites
|
||||||
|
|
||||||
- Remove any internal client from your device and download the client from the App Store/Google Play. This will help for
|
- Find the latest production build number for both iOS and Android in Slack. These are listed in #client-builds
|
||||||
testing as well as retrieving the build number.
|
- Production builds always send the Version Number and Build Number in the Slack message. Search for the latest
|
||||||
- You should have signed in to EAS locally through npx eas login. You will need to modify the build number in a
|
production version number, and you should find the correct information.
|
||||||
subsequent step.
|
|
||||||
- Identify the build number of the production app you want to deploy an update for. iOS and Android build numbers are
|

|
||||||
divergent, so you will need to find both
|
|
||||||
|
- It may also be useful to check the current production clients for these values. This will also help for testing. Note
|
||||||
|
that you will need to _fully_ remove the existing internal client build from your device, otherwise the given values in
|
||||||
|
the app may differ from the actual production values.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
- You should have signed in to EAS locally through npx eas login. You will need to modify the build number in a
|
||||||
|
subsequent step.
|
||||||
- Ensure that the commit the initial client was cut from is properly tagged in git. The tag should be in the format of 1.X.0
|
- Ensure that the commit the initial client was cut from is properly tagged in git. The tag should be in the format of 1.X.0
|
||||||
- Note: If the commit is not properly tagged, then the OTA deployment will simply fail since the GitHub Action will
|
- Note: If the commit is not properly tagged, then the OTA deployment will simply fail since the GitHub Action will
|
||||||
not be able to find a commit to fingerprint and diff against.
|
not be able to find a commit to fingerprint and diff against.
|
||||||
@@ -38,14 +43,17 @@ to create your branch from, this should be properly set.
|
|||||||
|
|
||||||
### Deployment
|
### Deployment
|
||||||
|
|
||||||
- Update the build number through EAS
|
- Update the build number through EAS to match the build numbers of the
|
||||||
|
production iOS/Android apps
|
||||||
- Note: This isn’t strictly necessary, but having a step that takes you off of GitHub and into the terminal provides
|
- Note: This isn’t strictly necessary, but having a step that takes you off of GitHub and into the terminal provides
|
||||||
a little “friction” to avoid fat fingering a release. Since there are legitimate reasons to just “click and deploy”
|
a little “friction” to avoid fat fingering a release. Since there are legitimate reasons to just “click and deploy”
|
||||||
for internal builds, I felt it useful to make sure it doesn’t accidentally become a prod deployment.
|
for internal builds, I felt it useful to make sure it doesn’t accidentally become a prod deployment.
|
||||||
- Set the build number to the appropriate build number found in the prerequisite steps. Again, this should be the
|
- Set the build numbers to the values found in the prerequisite steps. Again, this should be the
|
||||||
build number for the current production release you want to deploy for.
|
build number for the current production release you want to deploy for.
|
||||||
- `npx eas build:version:set -p ios`
|
- `npx eas build:version:set -p ios`
|
||||||
- `npx eas build:version:set -p android`
|
- `npx eas build:version:set -p android`
|
||||||
|
- These steps should spit out what the current build number is, save those values
|
||||||
|
for later too
|
||||||
- Run the deployment
|
- Run the deployment
|
||||||
- Navigate to https://github.com/bluesky-social/social-app/actions/workflows/bundle-deploy-eas-update.yml
|
- Navigate to https://github.com/bluesky-social/social-app/actions/workflows/bundle-deploy-eas-update.yml
|
||||||
- Select the “Run Workflow” dropdown
|
- Select the “Run Workflow” dropdown
|
||||||
@@ -79,3 +87,9 @@ In about five minutes, the new deployment should be available for download. To t
|
|||||||
- Launch the app once and wait approximately 15 seconds
|
- Launch the app once and wait approximately 15 seconds
|
||||||
- Relaunch the app
|
- Relaunch the app
|
||||||
- Check the Settings page and scroll to the bottom. The commit hash should now be the latest commit on your deployed branch.
|
- Check the Settings page and scroll to the bottom. The commit hash should now be the latest commit on your deployed branch.
|
||||||
|
|
||||||
|
### Post Deployment
|
||||||
|
|
||||||
|
- Reset both platforms build numbers to what they were before the OTA
|
||||||
|
deployment. These values should have been logged by the EAS CLI when you
|
||||||
|
reset them to the production values prior to OTA.
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 99 KiB |
+1
-1
@@ -49,7 +49,7 @@
|
|||||||
"open-analyzer": "EXPO_PUBLIC_OPEN_ANALYZER=1 yarn build-web"
|
"open-analyzer": "EXPO_PUBLIC_OPEN_ANALYZER=1 yarn build-web"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@atproto/api": "^0.12.14",
|
"@atproto/api": "^0.12.16",
|
||||||
"@bam.tech/react-native-image-resizer": "^3.0.4",
|
"@bam.tech/react-native-image-resizer": "^3.0.4",
|
||||||
"@braintree/sanitize-url": "^6.0.2",
|
"@braintree/sanitize-url": "^6.0.2",
|
||||||
"@discord/bottom-sheet": "bluesky-social/react-native-bottom-sheet",
|
"@discord/bottom-sheet": "bluesky-social/react-native-bottom-sheet",
|
||||||
|
|||||||
Executable
+9
@@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
outputIos=$(eas build:version:get -p ios)
|
||||||
|
outputAndroid=$(eas build:version:get -p android)
|
||||||
|
BSKY_IOS_BUILD_NUMBER=${outputIos#*buildNumber - }
|
||||||
|
BSKY_ANDROID_VERSION_CODE=${outputAndroid#*versionCode - }
|
||||||
|
|
||||||
|
echo PACKAGE_VERSION="$(jq -r '.version' package.json)" > "$GITHUB_OUTPUT"
|
||||||
|
echo BSKY_IOS_BUILD_NUMBER=$BSKY_IOS_BUILD_NUMBER >> "$GITHUB_OUTPUT"
|
||||||
|
echo BSKY_ANDROID_VERSION_CODE=$BSKY_ANDROID_VERSION_CODE >> "$GITHUB_OUTPUT"
|
||||||
@@ -16,6 +16,7 @@ import {sanitizeDisplayName} from '#/lib/strings/display-names'
|
|||||||
import {sanitizeHandle} from '#/lib/strings/handles'
|
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||||
import {isWeb} from '#/platform/detection'
|
import {isWeb} from '#/platform/detection'
|
||||||
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
||||||
|
import {useListConvosQuery} from '#/state/queries/messages/list-converations'
|
||||||
import {useProfileFollowsQuery} from '#/state/queries/profile-follows'
|
import {useProfileFollowsQuery} from '#/state/queries/profile-follows'
|
||||||
import {useSession} from '#/state/session'
|
import {useSession} from '#/state/session'
|
||||||
import {useActorAutocompleteQuery} from 'state/queries/actor-autocomplete'
|
import {useActorAutocompleteQuery} from 'state/queries/actor-autocomplete'
|
||||||
@@ -55,9 +56,11 @@ type Item =
|
|||||||
export function SearchablePeopleList({
|
export function SearchablePeopleList({
|
||||||
title,
|
title,
|
||||||
onSelectChat,
|
onSelectChat,
|
||||||
|
showRecentConvos,
|
||||||
}: {
|
}: {
|
||||||
title: string
|
title: string
|
||||||
onSelectChat: (did: string) => void
|
onSelectChat: (did: string) => void
|
||||||
|
showRecentConvos?: boolean
|
||||||
}) {
|
}) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
@@ -75,6 +78,7 @@ export function SearchablePeopleList({
|
|||||||
isFetching,
|
isFetching,
|
||||||
} = useActorAutocompleteQuery(searchText, true, 12)
|
} = useActorAutocompleteQuery(searchText, true, 12)
|
||||||
const {data: follows} = useProfileFollowsQuery(currentAccount?.did)
|
const {data: follows} = useProfileFollowsQuery(currentAccount?.did)
|
||||||
|
const {data: convos} = useListConvosQuery({enabled: showRecentConvos})
|
||||||
|
|
||||||
const items = useMemo(() => {
|
const items = useMemo(() => {
|
||||||
let _items: Item[] = []
|
let _items: Item[] = []
|
||||||
@@ -103,7 +107,65 @@ export function SearchablePeopleList({
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (follows) {
|
const placeholders: Item[] = Array(10)
|
||||||
|
.fill(0)
|
||||||
|
.map((_, i) => ({
|
||||||
|
type: 'placeholder',
|
||||||
|
key: i + '',
|
||||||
|
}))
|
||||||
|
|
||||||
|
if (showRecentConvos) {
|
||||||
|
if (convos && follows) {
|
||||||
|
const usedDids = new Set()
|
||||||
|
|
||||||
|
for (const page of convos.pages) {
|
||||||
|
for (const convo of page.convos) {
|
||||||
|
const profiles = convo.members.filter(
|
||||||
|
m => m.did !== currentAccount?.did,
|
||||||
|
)
|
||||||
|
|
||||||
|
for (const profile of profiles) {
|
||||||
|
if (usedDids.has(profile.did)) continue
|
||||||
|
|
||||||
|
usedDids.add(profile.did)
|
||||||
|
|
||||||
|
_items.push({
|
||||||
|
type: 'profile',
|
||||||
|
key: profile.did,
|
||||||
|
enabled: true,
|
||||||
|
profile,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let followsItems: typeof _items = []
|
||||||
|
|
||||||
|
for (const page of follows.pages) {
|
||||||
|
for (const profile of page.follows) {
|
||||||
|
if (usedDids.has(profile.did)) continue
|
||||||
|
|
||||||
|
followsItems.push({
|
||||||
|
type: 'profile',
|
||||||
|
key: profile.did,
|
||||||
|
enabled: canBeMessaged(profile),
|
||||||
|
profile,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// only sort follows
|
||||||
|
followsItems = followsItems.sort(a => {
|
||||||
|
// @ts-ignore
|
||||||
|
return a.enabled ? -1 : 1
|
||||||
|
})
|
||||||
|
|
||||||
|
// then append
|
||||||
|
_items.push(...followsItems)
|
||||||
|
} else {
|
||||||
|
_items.push(...placeholders)
|
||||||
|
}
|
||||||
|
} else if (follows) {
|
||||||
for (const page of follows.pages) {
|
for (const page of follows.pages) {
|
||||||
for (const profile of page.follows) {
|
for (const profile of page.follows) {
|
||||||
_items.push({
|
_items.push({
|
||||||
@@ -120,19 +182,21 @@ export function SearchablePeopleList({
|
|||||||
return a.enabled ? -1 : 1
|
return a.enabled ? -1 : 1
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Array(10)
|
_items.push(...placeholders)
|
||||||
.fill(0)
|
|
||||||
.forEach((_, i) => {
|
|
||||||
_items.push({
|
|
||||||
type: 'placeholder',
|
|
||||||
key: i + '',
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return _items
|
return _items
|
||||||
}, [_, searchText, results, isError, currentAccount?.did, follows])
|
}, [
|
||||||
|
_,
|
||||||
|
searchText,
|
||||||
|
results,
|
||||||
|
isError,
|
||||||
|
currentAccount?.did,
|
||||||
|
follows,
|
||||||
|
convos,
|
||||||
|
showRecentConvos,
|
||||||
|
])
|
||||||
|
|
||||||
if (searchText && !isFetching && !items.length && !isError) {
|
if (searchText && !isFetching && !items.length && !isError) {
|
||||||
items.push({type: 'empty', key: 'empty', message: _(msg`No results`)})
|
items.push({type: 'empty', key: 'empty', message: _(msg`No results`)})
|
||||||
@@ -331,11 +395,13 @@ function ProfileCard({
|
|||||||
/>
|
/>
|
||||||
<View style={[a.flex_1, a.gap_2xs]}>
|
<View style={[a.flex_1, a.gap_2xs]}>
|
||||||
<Text
|
<Text
|
||||||
style={[t.atoms.text, a.font_bold, a.leading_snug]}
|
style={[t.atoms.text, a.font_bold, a.leading_tight]}
|
||||||
numberOfLines={1}>
|
numberOfLines={1}>
|
||||||
{displayName}
|
{displayName}
|
||||||
</Text>
|
</Text>
|
||||||
<Text style={t.atoms.text_contrast_high} numberOfLines={2}>
|
<Text
|
||||||
|
style={[a.leading_tight, t.atoms.text_contrast_high]}
|
||||||
|
numberOfLines={2}>
|
||||||
{!enabled ? <Trans>{handle} can't be messaged</Trans> : handle}
|
{!enabled ? <Trans>{handle} can't be messaged</Trans> : handle}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ export function SendViaChatDialog({
|
|||||||
<SearchablePeopleList
|
<SearchablePeopleList
|
||||||
title={_(msg`Send post to...`)}
|
title={_(msg`Send post to...`)}
|
||||||
onSelectChat={onCreateChat}
|
onSelectChat={onCreateChat}
|
||||||
|
showRecentConvos
|
||||||
/>
|
/>
|
||||||
</Dialog.Outer>
|
</Dialog.Outer>
|
||||||
)
|
)
|
||||||
|
|||||||
+1001
-844
File diff suppressed because it is too large
Load Diff
+1001
-844
File diff suppressed because it is too large
Load Diff
+999
-842
File diff suppressed because it is too large
Load Diff
+1001
-844
File diff suppressed because it is too large
Load Diff
+1001
-844
File diff suppressed because it is too large
Load Diff
+949
-992
File diff suppressed because it is too large
Load Diff
+1200
-1178
File diff suppressed because it is too large
Load Diff
+1000
-843
File diff suppressed because it is too large
Load Diff
+1001
-844
File diff suppressed because it is too large
Load Diff
+1001
-844
File diff suppressed because it is too large
Load Diff
+926
-956
File diff suppressed because it is too large
Load Diff
+914
-926
File diff suppressed because it is too large
Load Diff
+1001
-844
File diff suppressed because it is too large
Load Diff
+1001
-844
File diff suppressed because it is too large
Load Diff
+1002
-845
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+1007
-1019
File diff suppressed because it is too large
Load Diff
@@ -4,18 +4,27 @@ import {useSafeAreaInsets} from 'react-native-safe-area-context'
|
|||||||
import {msg, Trans} from '@lingui/macro'
|
import {msg, Trans} from '@lingui/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {useFocusEffect} from '@react-navigation/native'
|
import {useFocusEffect} from '@react-navigation/native'
|
||||||
|
import {useQueryClient} from '@tanstack/react-query'
|
||||||
|
|
||||||
import {useAccountSwitcher} from '#/lib/hooks/useAccountSwitcher'
|
import {useAccountSwitcher} from '#/lib/hooks/useAccountSwitcher'
|
||||||
|
import {logger} from '#/logger'
|
||||||
import {isWeb} from '#/platform/detection'
|
import {isWeb} from '#/platform/detection'
|
||||||
import {type SessionAccount, useSession, useSessionApi} from '#/state/session'
|
import {
|
||||||
|
type SessionAccount,
|
||||||
|
useAgent,
|
||||||
|
useSession,
|
||||||
|
useSessionApi,
|
||||||
|
} from '#/state/session'
|
||||||
import {useSetMinimalShellMode} from '#/state/shell'
|
import {useSetMinimalShellMode} from '#/state/shell'
|
||||||
import {useLoggedOutViewControls} from '#/state/shell/logged-out'
|
import {useLoggedOutViewControls} from '#/state/shell/logged-out'
|
||||||
import {ScrollView} from '#/view/com/util/Views'
|
import {ScrollView} from '#/view/com/util/Views'
|
||||||
import {Logo} from '#/view/icons/Logo'
|
import {Logo} from '#/view/icons/Logo'
|
||||||
import {atoms as a, useTheme} from '#/alf'
|
import {atoms as a, useTheme} from '#/alf'
|
||||||
import {AccountList} from '#/components/AccountList'
|
import {AccountList} from '#/components/AccountList'
|
||||||
import {Button, ButtonText} from '#/components/Button'
|
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
||||||
import {Divider} from '#/components/Divider'
|
import {Divider} from '#/components/Divider'
|
||||||
|
import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo'
|
||||||
|
import {Loader} from '#/components/Loader'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
|
|
||||||
const COL_WIDTH = 400
|
const COL_WIDTH = 400
|
||||||
@@ -30,6 +39,10 @@ export function Deactivated() {
|
|||||||
const hasOtherAccounts = accounts.length > 1
|
const hasOtherAccounts = accounts.length > 1
|
||||||
const setMinimalShellMode = useSetMinimalShellMode()
|
const setMinimalShellMode = useSetMinimalShellMode()
|
||||||
const {logout} = useSessionApi()
|
const {logout} = useSessionApi()
|
||||||
|
const agent = useAgent()
|
||||||
|
const [pending, setPending] = React.useState(false)
|
||||||
|
const [error, setError] = React.useState<string | undefined>()
|
||||||
|
const queryClient = useQueryClient()
|
||||||
|
|
||||||
useFocusEffect(
|
useFocusEffect(
|
||||||
React.useCallback(() => {
|
React.useCallback(() => {
|
||||||
@@ -62,6 +75,34 @@ export function Deactivated() {
|
|||||||
logout('Deactivated')
|
logout('Deactivated')
|
||||||
}, [logout])
|
}, [logout])
|
||||||
|
|
||||||
|
const handleActivate = React.useCallback(async () => {
|
||||||
|
try {
|
||||||
|
setPending(true)
|
||||||
|
await agent.com.atproto.server.activateAccount()
|
||||||
|
await queryClient.resetQueries()
|
||||||
|
await agent.resumeSession(agent.session!)
|
||||||
|
} catch (e: any) {
|
||||||
|
switch (e.message) {
|
||||||
|
case 'Bad token scope':
|
||||||
|
setError(
|
||||||
|
_(
|
||||||
|
msg`You're logged in with an App Password. Please log in with your main password to continue deactivating your account.`,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
setError(_(msg`Something went wrong, please try again`))
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.error(e, {
|
||||||
|
context: 'Failed to activate account',
|
||||||
|
})
|
||||||
|
} finally {
|
||||||
|
setPending(false)
|
||||||
|
}
|
||||||
|
}, [_, agent, setPending, setError, queryClient])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={[a.h_full_vh, a.flex_1, t.atoms.bg]}>
|
<View style={[a.h_full_vh, a.flex_1, t.atoms.bg]}>
|
||||||
<ScrollView
|
<ScrollView
|
||||||
@@ -104,10 +145,11 @@ export function Deactivated() {
|
|||||||
size="medium"
|
size="medium"
|
||||||
variant="solid"
|
variant="solid"
|
||||||
color="primary"
|
color="primary"
|
||||||
onPress={() => setShowLoggedOut(true)}>
|
onPress={handleActivate}>
|
||||||
<ButtonText>
|
<ButtonText>
|
||||||
<Trans>Yes, reactivate my account</Trans>
|
<Trans>Yes, reactivate my account</Trans>
|
||||||
</ButtonText>
|
</ButtonText>
|
||||||
|
{pending && <ButtonIcon icon={Loader} position="right" />}
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
label={_(msg`Cancel reactivation and log out`)}
|
label={_(msg`Cancel reactivation and log out`)}
|
||||||
@@ -120,6 +162,21 @@ export function Deactivated() {
|
|||||||
</ButtonText>
|
</ButtonText>
|
||||||
</Button>
|
</Button>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
|
{error && (
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
a.flex_row,
|
||||||
|
a.gap_sm,
|
||||||
|
a.mt_md,
|
||||||
|
a.p_md,
|
||||||
|
a.rounded_sm,
|
||||||
|
t.atoms.bg_contrast_25,
|
||||||
|
]}>
|
||||||
|
<CircleInfo size="md" fill={t.palette.negative_400} />
|
||||||
|
<Text style={[a.flex_1, a.leading_snug]}>{error}</Text>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<View style={[a.pb_3xl]}>
|
<View style={[a.pb_3xl]}>
|
||||||
|
|||||||
@@ -81,15 +81,17 @@ let ProfileHeaderShell = ({
|
|||||||
|
|
||||||
{children}
|
{children}
|
||||||
|
|
||||||
<View
|
{!isPlaceholderProfile && (
|
||||||
style={[a.px_lg, a.pb_sm]}
|
<View
|
||||||
pointerEvents={isIOS ? 'auto' : 'box-none'}>
|
style={[a.px_lg, a.pb_sm]}
|
||||||
{isMe ? (
|
pointerEvents={isIOS ? 'auto' : 'box-none'}>
|
||||||
<LabelsOnMe details={{did: profile.did}} labels={profile.labels} />
|
{isMe ? (
|
||||||
) : (
|
<LabelsOnMe details={{did: profile.did}} labels={profile.labels} />
|
||||||
<ProfileHeaderAlerts moderation={moderation} />
|
) : (
|
||||||
)}
|
<ProfileHeaderAlerts moderation={moderation} />
|
||||||
</View>
|
)}
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
|
||||||
{!isDesktop && !hideBackButton && (
|
{!isDesktop && !hideBackButton && (
|
||||||
<TouchableWithoutFeedback
|
<TouchableWithoutFeedback
|
||||||
|
|||||||
@@ -3,9 +3,14 @@ import {View} from 'react-native'
|
|||||||
import {msg, Trans} from '@lingui/macro'
|
import {msg, Trans} from '@lingui/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
|
|
||||||
import {atoms as a, useTheme} from '#/alf'
|
import {logger} from '#/logger'
|
||||||
|
import {useAgent, useSessionApi} from '#/state/session'
|
||||||
|
import {atoms as a, useBreakpoints, useTheme} from '#/alf'
|
||||||
|
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
||||||
import {DialogOuterProps} from '#/components/Dialog'
|
import {DialogOuterProps} from '#/components/Dialog'
|
||||||
import {Divider} from '#/components/Divider'
|
import {Divider} from '#/components/Divider'
|
||||||
|
import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo'
|
||||||
|
import {Loader} from '#/components/Loader'
|
||||||
import * as Prompt from '#/components/Prompt'
|
import * as Prompt from '#/components/Prompt'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
|
|
||||||
@@ -13,12 +18,58 @@ export function DeactivateAccountDialog({
|
|||||||
control,
|
control,
|
||||||
}: {
|
}: {
|
||||||
control: DialogOuterProps['control']
|
control: DialogOuterProps['control']
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<Prompt.Outer control={control}>
|
||||||
|
<DeactivateAccountDialogInner control={control} />
|
||||||
|
</Prompt.Outer>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function DeactivateAccountDialogInner({
|
||||||
|
control,
|
||||||
|
}: {
|
||||||
|
control: DialogOuterProps['control']
|
||||||
}) {
|
}) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
|
const {gtMobile} = useBreakpoints()
|
||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
|
const agent = useAgent()
|
||||||
|
const {logout} = useSessionApi()
|
||||||
|
const [pending, setPending] = React.useState(false)
|
||||||
|
const [error, setError] = React.useState<string | undefined>()
|
||||||
|
|
||||||
|
const handleDeactivate = React.useCallback(async () => {
|
||||||
|
try {
|
||||||
|
setPending(true)
|
||||||
|
await agent.com.atproto.server.deactivateAccount({})
|
||||||
|
control.close(() => {
|
||||||
|
logout('Deactivated')
|
||||||
|
})
|
||||||
|
} catch (e: any) {
|
||||||
|
switch (e.message) {
|
||||||
|
case 'Bad token scope':
|
||||||
|
setError(
|
||||||
|
_(
|
||||||
|
msg`You're logged in with an App Password. Please log in with your main password to continue deactivating your account.`,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
setError(_(msg`Something went wrong, please try again`))
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.error(e, {
|
||||||
|
context: 'Failed to deactivate account',
|
||||||
|
})
|
||||||
|
} finally {
|
||||||
|
setPending(false)
|
||||||
|
}
|
||||||
|
}, [agent, control, logout, _, setPending])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Prompt.Outer control={control} testID="confirmModal">
|
<>
|
||||||
<Prompt.TitleText>{_(msg`Deactivate account`)}</Prompt.TitleText>
|
<Prompt.TitleText>{_(msg`Deactivate account`)}</Prompt.TitleText>
|
||||||
<Prompt.DescriptionText>
|
<Prompt.DescriptionText>
|
||||||
<Trans>
|
<Trans>
|
||||||
@@ -48,13 +99,32 @@ export function DeactivateAccountDialog({
|
|||||||
<Divider />
|
<Divider />
|
||||||
</View>
|
</View>
|
||||||
<Prompt.Actions>
|
<Prompt.Actions>
|
||||||
<Prompt.Action
|
<Button
|
||||||
cta={_(msg`Yes, deactivate`)}
|
variant="solid"
|
||||||
onPress={() => {}}
|
|
||||||
color="negative"
|
color="negative"
|
||||||
/>
|
size={gtMobile ? 'small' : 'medium'}
|
||||||
|
label={_(msg`Yes, deactivate`)}
|
||||||
|
onPress={handleDeactivate}>
|
||||||
|
<ButtonText>{_(msg`Yes, deactivate`)}</ButtonText>
|
||||||
|
{pending && <ButtonIcon icon={Loader} position="right" />}
|
||||||
|
</Button>
|
||||||
<Prompt.Cancel />
|
<Prompt.Cancel />
|
||||||
</Prompt.Actions>
|
</Prompt.Actions>
|
||||||
</Prompt.Outer>
|
|
||||||
|
{error && (
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
a.flex_row,
|
||||||
|
a.gap_sm,
|
||||||
|
a.mt_md,
|
||||||
|
a.p_md,
|
||||||
|
a.rounded_sm,
|
||||||
|
t.atoms.bg_contrast_25,
|
||||||
|
]}>
|
||||||
|
<CircleInfo size="md" fill={t.palette.negative_400} />
|
||||||
|
<Text style={[a.flex_1, a.leading_snug]}>{error}</Text>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,9 +18,12 @@ const accountSchema = z.object({
|
|||||||
refreshJwt: z.string().optional(), // optional because it can expire
|
refreshJwt: z.string().optional(), // optional because it can expire
|
||||||
accessJwt: z.string().optional(), // optional because it can expire
|
accessJwt: z.string().optional(), // optional because it can expire
|
||||||
signupQueued: z.boolean().optional(),
|
signupQueued: z.boolean().optional(),
|
||||||
status: z
|
active: z.boolean().optional(), // optional for backwards compat
|
||||||
.enum(['active', 'takendown', 'suspended', 'deactivated'])
|
/**
|
||||||
.optional(),
|
* Known values: takendown, suspended, deactivated
|
||||||
|
* @see https://github.com/bluesky-social/atproto/blob/5441fbde9ed3b22463e91481ec80cb095643e141/lexicons/com/atproto/server/getSession.json
|
||||||
|
*/
|
||||||
|
status: z.string().optional(),
|
||||||
pdsUrl: z.string().optional(),
|
pdsUrl: z.string().optional(),
|
||||||
})
|
})
|
||||||
export type PersistedAccount = z.infer<typeof accountSchema>
|
export type PersistedAccount = z.infer<typeof accountSchema>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import AsyncStorage from '@react-native-async-storage/async-storage'
|
import AsyncStorage from '@react-native-async-storage/async-storage'
|
||||||
|
|
||||||
import {Schema, schema} from '#/state/persisted/schema'
|
|
||||||
import {logger} from '#/logger'
|
import {logger} from '#/logger'
|
||||||
|
import {Schema, schema} from '#/state/persisted/schema'
|
||||||
|
|
||||||
const BSKY_STORAGE = 'BSKY_STORAGE'
|
const BSKY_STORAGE = 'BSKY_STORAGE'
|
||||||
|
|
||||||
@@ -13,8 +13,19 @@ export async function write(value: Schema) {
|
|||||||
export async function read(): Promise<Schema | undefined> {
|
export async function read(): Promise<Schema | undefined> {
|
||||||
const rawData = await AsyncStorage.getItem(BSKY_STORAGE)
|
const rawData = await AsyncStorage.getItem(BSKY_STORAGE)
|
||||||
const objData = rawData ? JSON.parse(rawData) : undefined
|
const objData = rawData ? JSON.parse(rawData) : undefined
|
||||||
if (schema.safeParse(objData).success) {
|
const parsed = schema.safeParse(objData)
|
||||||
|
if (parsed.success) {
|
||||||
return objData
|
return objData
|
||||||
|
} else {
|
||||||
|
const errors =
|
||||||
|
parsed.error?.errors?.map(e => ({
|
||||||
|
code: e.code,
|
||||||
|
// @ts-ignore exists on some types
|
||||||
|
expected: e?.expected,
|
||||||
|
path: e.path,
|
||||||
|
})) || []
|
||||||
|
logger.error(`persisted store: data failed validation on read`, {errors})
|
||||||
|
return undefined
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,10 +26,15 @@ import {useAgent, useSession} from '#/state/session'
|
|||||||
export const RQKEY = ['convo-list']
|
export const RQKEY = ['convo-list']
|
||||||
type RQPageParam = string | undefined
|
type RQPageParam = string | undefined
|
||||||
|
|
||||||
export function useListConvosQuery() {
|
export function useListConvosQuery({
|
||||||
|
enabled,
|
||||||
|
}: {
|
||||||
|
enabled?: boolean
|
||||||
|
} = {}) {
|
||||||
const agent = useAgent()
|
const agent = useAgent()
|
||||||
|
|
||||||
return useInfiniteQuery({
|
return useInfiniteQuery({
|
||||||
|
enabled,
|
||||||
queryKey: RQKEY,
|
queryKey: RQKEY,
|
||||||
queryFn: async ({pageParam}) => {
|
queryFn: async ({pageParam}) => {
|
||||||
const {data} = await agent.api.chat.bsky.convo.listConvos(
|
const {data} = await agent.api.chat.bsky.convo.listConvos(
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ describe('session', () => {
|
|||||||
|
|
||||||
const agent = new BskyAgent({service: 'https://alice.com'})
|
const agent = new BskyAgent({service: 'https://alice.com'})
|
||||||
agent.session = {
|
agent.session = {
|
||||||
|
active: true,
|
||||||
did: 'alice-did',
|
did: 'alice-did',
|
||||||
handle: 'alice.test',
|
handle: 'alice.test',
|
||||||
accessJwt: 'alice-access-jwt-1',
|
accessJwt: 'alice-access-jwt-1',
|
||||||
@@ -50,6 +51,7 @@ describe('session', () => {
|
|||||||
"accounts": [
|
"accounts": [
|
||||||
{
|
{
|
||||||
"accessJwt": "alice-access-jwt-1",
|
"accessJwt": "alice-access-jwt-1",
|
||||||
|
"active": true,
|
||||||
"did": "alice-did",
|
"did": "alice-did",
|
||||||
"email": undefined,
|
"email": undefined,
|
||||||
"emailAuthFactor": false,
|
"emailAuthFactor": false,
|
||||||
@@ -59,7 +61,7 @@ describe('session', () => {
|
|||||||
"refreshJwt": "alice-refresh-jwt-1",
|
"refreshJwt": "alice-refresh-jwt-1",
|
||||||
"service": "https://alice.com/",
|
"service": "https://alice.com/",
|
||||||
"signupQueued": false,
|
"signupQueued": false,
|
||||||
"status": "active",
|
"status": undefined,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"currentAgentState": {
|
"currentAgentState": {
|
||||||
@@ -88,6 +90,7 @@ describe('session', () => {
|
|||||||
"accounts": [
|
"accounts": [
|
||||||
{
|
{
|
||||||
"accessJwt": undefined,
|
"accessJwt": undefined,
|
||||||
|
"active": true,
|
||||||
"did": "alice-did",
|
"did": "alice-did",
|
||||||
"email": undefined,
|
"email": undefined,
|
||||||
"emailAuthFactor": false,
|
"emailAuthFactor": false,
|
||||||
@@ -97,7 +100,7 @@ describe('session', () => {
|
|||||||
"refreshJwt": undefined,
|
"refreshJwt": undefined,
|
||||||
"service": "https://alice.com/",
|
"service": "https://alice.com/",
|
||||||
"signupQueued": false,
|
"signupQueued": false,
|
||||||
"status": "active",
|
"status": undefined,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"currentAgentState": {
|
"currentAgentState": {
|
||||||
@@ -116,6 +119,7 @@ describe('session', () => {
|
|||||||
|
|
||||||
const agent1 = new BskyAgent({service: 'https://alice.com'})
|
const agent1 = new BskyAgent({service: 'https://alice.com'})
|
||||||
agent1.session = {
|
agent1.session = {
|
||||||
|
active: true,
|
||||||
did: 'alice-did',
|
did: 'alice-did',
|
||||||
handle: 'alice.test',
|
handle: 'alice.test',
|
||||||
accessJwt: 'alice-access-jwt-1',
|
accessJwt: 'alice-access-jwt-1',
|
||||||
@@ -138,6 +142,7 @@ describe('session', () => {
|
|||||||
"accounts": [
|
"accounts": [
|
||||||
{
|
{
|
||||||
"accessJwt": "alice-access-jwt-1",
|
"accessJwt": "alice-access-jwt-1",
|
||||||
|
"active": true,
|
||||||
"did": "alice-did",
|
"did": "alice-did",
|
||||||
"email": undefined,
|
"email": undefined,
|
||||||
"emailAuthFactor": false,
|
"emailAuthFactor": false,
|
||||||
@@ -147,7 +152,7 @@ describe('session', () => {
|
|||||||
"refreshJwt": "alice-refresh-jwt-1",
|
"refreshJwt": "alice-refresh-jwt-1",
|
||||||
"service": "https://alice.com/",
|
"service": "https://alice.com/",
|
||||||
"signupQueued": false,
|
"signupQueued": false,
|
||||||
"status": "active",
|
"status": undefined,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"currentAgentState": {
|
"currentAgentState": {
|
||||||
@@ -162,6 +167,7 @@ describe('session', () => {
|
|||||||
|
|
||||||
const agent2 = new BskyAgent({service: 'https://bob.com'})
|
const agent2 = new BskyAgent({service: 'https://bob.com'})
|
||||||
agent2.session = {
|
agent2.session = {
|
||||||
|
active: true,
|
||||||
did: 'bob-did',
|
did: 'bob-did',
|
||||||
handle: 'bob.test',
|
handle: 'bob.test',
|
||||||
accessJwt: 'bob-access-jwt-1',
|
accessJwt: 'bob-access-jwt-1',
|
||||||
@@ -186,6 +192,7 @@ describe('session', () => {
|
|||||||
"accounts": [
|
"accounts": [
|
||||||
{
|
{
|
||||||
"accessJwt": "bob-access-jwt-1",
|
"accessJwt": "bob-access-jwt-1",
|
||||||
|
"active": true,
|
||||||
"did": "bob-did",
|
"did": "bob-did",
|
||||||
"email": undefined,
|
"email": undefined,
|
||||||
"emailAuthFactor": false,
|
"emailAuthFactor": false,
|
||||||
@@ -195,10 +202,11 @@ describe('session', () => {
|
|||||||
"refreshJwt": "bob-refresh-jwt-1",
|
"refreshJwt": "bob-refresh-jwt-1",
|
||||||
"service": "https://bob.com/",
|
"service": "https://bob.com/",
|
||||||
"signupQueued": false,
|
"signupQueued": false,
|
||||||
"status": "active",
|
"status": undefined,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"accessJwt": "alice-access-jwt-1",
|
"accessJwt": "alice-access-jwt-1",
|
||||||
|
"active": true,
|
||||||
"did": "alice-did",
|
"did": "alice-did",
|
||||||
"email": undefined,
|
"email": undefined,
|
||||||
"emailAuthFactor": false,
|
"emailAuthFactor": false,
|
||||||
@@ -208,7 +216,7 @@ describe('session', () => {
|
|||||||
"refreshJwt": "alice-refresh-jwt-1",
|
"refreshJwt": "alice-refresh-jwt-1",
|
||||||
"service": "https://alice.com/",
|
"service": "https://alice.com/",
|
||||||
"signupQueued": false,
|
"signupQueued": false,
|
||||||
"status": "active",
|
"status": undefined,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"currentAgentState": {
|
"currentAgentState": {
|
||||||
@@ -223,6 +231,7 @@ describe('session', () => {
|
|||||||
|
|
||||||
const agent3 = new BskyAgent({service: 'https://alice.com'})
|
const agent3 = new BskyAgent({service: 'https://alice.com'})
|
||||||
agent3.session = {
|
agent3.session = {
|
||||||
|
active: true,
|
||||||
did: 'alice-did',
|
did: 'alice-did',
|
||||||
handle: 'alice-updated.test',
|
handle: 'alice-updated.test',
|
||||||
accessJwt: 'alice-access-jwt-2',
|
accessJwt: 'alice-access-jwt-2',
|
||||||
@@ -247,6 +256,7 @@ describe('session', () => {
|
|||||||
"accounts": [
|
"accounts": [
|
||||||
{
|
{
|
||||||
"accessJwt": "alice-access-jwt-2",
|
"accessJwt": "alice-access-jwt-2",
|
||||||
|
"active": true,
|
||||||
"did": "alice-did",
|
"did": "alice-did",
|
||||||
"email": undefined,
|
"email": undefined,
|
||||||
"emailAuthFactor": false,
|
"emailAuthFactor": false,
|
||||||
@@ -256,10 +266,11 @@ describe('session', () => {
|
|||||||
"refreshJwt": "alice-refresh-jwt-2",
|
"refreshJwt": "alice-refresh-jwt-2",
|
||||||
"service": "https://alice.com/",
|
"service": "https://alice.com/",
|
||||||
"signupQueued": false,
|
"signupQueued": false,
|
||||||
"status": "active",
|
"status": undefined,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"accessJwt": "bob-access-jwt-1",
|
"accessJwt": "bob-access-jwt-1",
|
||||||
|
"active": true,
|
||||||
"did": "bob-did",
|
"did": "bob-did",
|
||||||
"email": undefined,
|
"email": undefined,
|
||||||
"emailAuthFactor": false,
|
"emailAuthFactor": false,
|
||||||
@@ -269,7 +280,7 @@ describe('session', () => {
|
|||||||
"refreshJwt": "bob-refresh-jwt-1",
|
"refreshJwt": "bob-refresh-jwt-1",
|
||||||
"service": "https://bob.com/",
|
"service": "https://bob.com/",
|
||||||
"signupQueued": false,
|
"signupQueued": false,
|
||||||
"status": "active",
|
"status": undefined,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"currentAgentState": {
|
"currentAgentState": {
|
||||||
@@ -284,6 +295,7 @@ describe('session', () => {
|
|||||||
|
|
||||||
const agent4 = new BskyAgent({service: 'https://jay.com'})
|
const agent4 = new BskyAgent({service: 'https://jay.com'})
|
||||||
agent4.session = {
|
agent4.session = {
|
||||||
|
active: true,
|
||||||
did: 'jay-did',
|
did: 'jay-did',
|
||||||
handle: 'jay.test',
|
handle: 'jay.test',
|
||||||
accessJwt: 'jay-access-jwt-1',
|
accessJwt: 'jay-access-jwt-1',
|
||||||
@@ -306,6 +318,7 @@ describe('session', () => {
|
|||||||
"accounts": [
|
"accounts": [
|
||||||
{
|
{
|
||||||
"accessJwt": "jay-access-jwt-1",
|
"accessJwt": "jay-access-jwt-1",
|
||||||
|
"active": true,
|
||||||
"did": "jay-did",
|
"did": "jay-did",
|
||||||
"email": undefined,
|
"email": undefined,
|
||||||
"emailAuthFactor": false,
|
"emailAuthFactor": false,
|
||||||
@@ -315,10 +328,11 @@ describe('session', () => {
|
|||||||
"refreshJwt": "jay-refresh-jwt-1",
|
"refreshJwt": "jay-refresh-jwt-1",
|
||||||
"service": "https://jay.com/",
|
"service": "https://jay.com/",
|
||||||
"signupQueued": false,
|
"signupQueued": false,
|
||||||
"status": "active",
|
"status": undefined,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"accessJwt": "alice-access-jwt-2",
|
"accessJwt": "alice-access-jwt-2",
|
||||||
|
"active": true,
|
||||||
"did": "alice-did",
|
"did": "alice-did",
|
||||||
"email": undefined,
|
"email": undefined,
|
||||||
"emailAuthFactor": false,
|
"emailAuthFactor": false,
|
||||||
@@ -328,10 +342,11 @@ describe('session', () => {
|
|||||||
"refreshJwt": "alice-refresh-jwt-2",
|
"refreshJwt": "alice-refresh-jwt-2",
|
||||||
"service": "https://alice.com/",
|
"service": "https://alice.com/",
|
||||||
"signupQueued": false,
|
"signupQueued": false,
|
||||||
"status": "active",
|
"status": undefined,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"accessJwt": "bob-access-jwt-1",
|
"accessJwt": "bob-access-jwt-1",
|
||||||
|
"active": true,
|
||||||
"did": "bob-did",
|
"did": "bob-did",
|
||||||
"email": undefined,
|
"email": undefined,
|
||||||
"emailAuthFactor": false,
|
"emailAuthFactor": false,
|
||||||
@@ -341,7 +356,7 @@ describe('session', () => {
|
|||||||
"refreshJwt": "bob-refresh-jwt-1",
|
"refreshJwt": "bob-refresh-jwt-1",
|
||||||
"service": "https://bob.com/",
|
"service": "https://bob.com/",
|
||||||
"signupQueued": false,
|
"signupQueued": false,
|
||||||
"status": "active",
|
"status": undefined,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"currentAgentState": {
|
"currentAgentState": {
|
||||||
@@ -374,6 +389,7 @@ describe('session', () => {
|
|||||||
"accounts": [
|
"accounts": [
|
||||||
{
|
{
|
||||||
"accessJwt": undefined,
|
"accessJwt": undefined,
|
||||||
|
"active": true,
|
||||||
"did": "jay-did",
|
"did": "jay-did",
|
||||||
"email": undefined,
|
"email": undefined,
|
||||||
"emailAuthFactor": false,
|
"emailAuthFactor": false,
|
||||||
@@ -383,10 +399,11 @@ describe('session', () => {
|
|||||||
"refreshJwt": undefined,
|
"refreshJwt": undefined,
|
||||||
"service": "https://jay.com/",
|
"service": "https://jay.com/",
|
||||||
"signupQueued": false,
|
"signupQueued": false,
|
||||||
"status": "active",
|
"status": undefined,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"accessJwt": undefined,
|
"accessJwt": undefined,
|
||||||
|
"active": true,
|
||||||
"did": "alice-did",
|
"did": "alice-did",
|
||||||
"email": undefined,
|
"email": undefined,
|
||||||
"emailAuthFactor": false,
|
"emailAuthFactor": false,
|
||||||
@@ -396,10 +413,11 @@ describe('session', () => {
|
|||||||
"refreshJwt": undefined,
|
"refreshJwt": undefined,
|
||||||
"service": "https://alice.com/",
|
"service": "https://alice.com/",
|
||||||
"signupQueued": false,
|
"signupQueued": false,
|
||||||
"status": "active",
|
"status": undefined,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"accessJwt": undefined,
|
"accessJwt": undefined,
|
||||||
|
"active": true,
|
||||||
"did": "bob-did",
|
"did": "bob-did",
|
||||||
"email": undefined,
|
"email": undefined,
|
||||||
"emailAuthFactor": false,
|
"emailAuthFactor": false,
|
||||||
@@ -409,7 +427,7 @@ describe('session', () => {
|
|||||||
"refreshJwt": undefined,
|
"refreshJwt": undefined,
|
||||||
"service": "https://bob.com/",
|
"service": "https://bob.com/",
|
||||||
"signupQueued": false,
|
"signupQueued": false,
|
||||||
"status": "active",
|
"status": undefined,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"currentAgentState": {
|
"currentAgentState": {
|
||||||
@@ -428,6 +446,7 @@ describe('session', () => {
|
|||||||
|
|
||||||
const agent1 = new BskyAgent({service: 'https://alice.com'})
|
const agent1 = new BskyAgent({service: 'https://alice.com'})
|
||||||
agent1.session = {
|
agent1.session = {
|
||||||
|
active: true,
|
||||||
did: 'alice-did',
|
did: 'alice-did',
|
||||||
handle: 'alice.test',
|
handle: 'alice.test',
|
||||||
accessJwt: 'alice-access-jwt-1',
|
accessJwt: 'alice-access-jwt-1',
|
||||||
@@ -459,6 +478,7 @@ describe('session', () => {
|
|||||||
"accounts": [
|
"accounts": [
|
||||||
{
|
{
|
||||||
"accessJwt": undefined,
|
"accessJwt": undefined,
|
||||||
|
"active": true,
|
||||||
"did": "alice-did",
|
"did": "alice-did",
|
||||||
"email": undefined,
|
"email": undefined,
|
||||||
"emailAuthFactor": false,
|
"emailAuthFactor": false,
|
||||||
@@ -468,7 +488,7 @@ describe('session', () => {
|
|||||||
"refreshJwt": undefined,
|
"refreshJwt": undefined,
|
||||||
"service": "https://alice.com/",
|
"service": "https://alice.com/",
|
||||||
"signupQueued": false,
|
"signupQueued": false,
|
||||||
"status": "active",
|
"status": undefined,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"currentAgentState": {
|
"currentAgentState": {
|
||||||
@@ -483,6 +503,7 @@ describe('session', () => {
|
|||||||
|
|
||||||
const agent2 = new BskyAgent({service: 'https://alice.com'})
|
const agent2 = new BskyAgent({service: 'https://alice.com'})
|
||||||
agent2.session = {
|
agent2.session = {
|
||||||
|
active: true,
|
||||||
did: 'alice-did',
|
did: 'alice-did',
|
||||||
handle: 'alice.test',
|
handle: 'alice.test',
|
||||||
accessJwt: 'alice-access-jwt-2',
|
accessJwt: 'alice-access-jwt-2',
|
||||||
@@ -504,6 +525,7 @@ describe('session', () => {
|
|||||||
"accounts": [
|
"accounts": [
|
||||||
{
|
{
|
||||||
"accessJwt": "alice-access-jwt-2",
|
"accessJwt": "alice-access-jwt-2",
|
||||||
|
"active": true,
|
||||||
"did": "alice-did",
|
"did": "alice-did",
|
||||||
"email": undefined,
|
"email": undefined,
|
||||||
"emailAuthFactor": false,
|
"emailAuthFactor": false,
|
||||||
@@ -513,7 +535,7 @@ describe('session', () => {
|
|||||||
"refreshJwt": "alice-refresh-jwt-2",
|
"refreshJwt": "alice-refresh-jwt-2",
|
||||||
"service": "https://alice.com/",
|
"service": "https://alice.com/",
|
||||||
"signupQueued": false,
|
"signupQueued": false,
|
||||||
"status": "active",
|
"status": undefined,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"currentAgentState": {
|
"currentAgentState": {
|
||||||
@@ -532,6 +554,7 @@ describe('session', () => {
|
|||||||
|
|
||||||
const agent1 = new BskyAgent({service: 'https://alice.com'})
|
const agent1 = new BskyAgent({service: 'https://alice.com'})
|
||||||
agent1.session = {
|
agent1.session = {
|
||||||
|
active: true,
|
||||||
did: 'alice-did',
|
did: 'alice-did',
|
||||||
handle: 'alice.test',
|
handle: 'alice.test',
|
||||||
accessJwt: 'alice-access-jwt-1',
|
accessJwt: 'alice-access-jwt-1',
|
||||||
@@ -576,6 +599,7 @@ describe('session', () => {
|
|||||||
|
|
||||||
const agent1 = new BskyAgent({service: 'https://alice.com'})
|
const agent1 = new BskyAgent({service: 'https://alice.com'})
|
||||||
agent1.session = {
|
agent1.session = {
|
||||||
|
active: true,
|
||||||
did: 'alice-did',
|
did: 'alice-did',
|
||||||
handle: 'alice.test',
|
handle: 'alice.test',
|
||||||
accessJwt: 'alice-access-jwt-1',
|
accessJwt: 'alice-access-jwt-1',
|
||||||
@@ -583,6 +607,7 @@ describe('session', () => {
|
|||||||
}
|
}
|
||||||
const agent2 = new BskyAgent({service: 'https://bob.com'})
|
const agent2 = new BskyAgent({service: 'https://bob.com'})
|
||||||
agent2.session = {
|
agent2.session = {
|
||||||
|
active: true,
|
||||||
did: 'bob-did',
|
did: 'bob-did',
|
||||||
handle: 'bob.test',
|
handle: 'bob.test',
|
||||||
accessJwt: 'bob-access-jwt-1',
|
accessJwt: 'bob-access-jwt-1',
|
||||||
@@ -616,6 +641,7 @@ describe('session', () => {
|
|||||||
"accounts": [
|
"accounts": [
|
||||||
{
|
{
|
||||||
"accessJwt": "bob-access-jwt-1",
|
"accessJwt": "bob-access-jwt-1",
|
||||||
|
"active": true,
|
||||||
"did": "bob-did",
|
"did": "bob-did",
|
||||||
"email": undefined,
|
"email": undefined,
|
||||||
"emailAuthFactor": false,
|
"emailAuthFactor": false,
|
||||||
@@ -625,7 +651,7 @@ describe('session', () => {
|
|||||||
"refreshJwt": "bob-refresh-jwt-1",
|
"refreshJwt": "bob-refresh-jwt-1",
|
||||||
"service": "https://bob.com/",
|
"service": "https://bob.com/",
|
||||||
"signupQueued": false,
|
"signupQueued": false,
|
||||||
"status": "active",
|
"status": undefined,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"currentAgentState": {
|
"currentAgentState": {
|
||||||
@@ -653,6 +679,7 @@ describe('session', () => {
|
|||||||
|
|
||||||
const agent1 = new BskyAgent({service: 'https://alice.com'})
|
const agent1 = new BskyAgent({service: 'https://alice.com'})
|
||||||
agent1.session = {
|
agent1.session = {
|
||||||
|
active: true,
|
||||||
did: 'alice-did',
|
did: 'alice-did',
|
||||||
handle: 'alice.test',
|
handle: 'alice.test',
|
||||||
accessJwt: 'alice-access-jwt-1',
|
accessJwt: 'alice-access-jwt-1',
|
||||||
@@ -669,6 +696,7 @@ describe('session', () => {
|
|||||||
expect(state.currentAgentState.did).toBe('alice-did')
|
expect(state.currentAgentState.did).toBe('alice-did')
|
||||||
|
|
||||||
agent1.session = {
|
agent1.session = {
|
||||||
|
active: true,
|
||||||
did: 'alice-did',
|
did: 'alice-did',
|
||||||
handle: 'alice-updated.test',
|
handle: 'alice-updated.test',
|
||||||
accessJwt: 'alice-access-jwt-2',
|
accessJwt: 'alice-access-jwt-2',
|
||||||
@@ -697,6 +725,7 @@ describe('session', () => {
|
|||||||
"accounts": [
|
"accounts": [
|
||||||
{
|
{
|
||||||
"accessJwt": "alice-access-jwt-2",
|
"accessJwt": "alice-access-jwt-2",
|
||||||
|
"active": true,
|
||||||
"did": "alice-did",
|
"did": "alice-did",
|
||||||
"email": "alice@foo.bar",
|
"email": "alice@foo.bar",
|
||||||
"emailAuthFactor": false,
|
"emailAuthFactor": false,
|
||||||
@@ -706,7 +735,7 @@ describe('session', () => {
|
|||||||
"refreshJwt": "alice-refresh-jwt-2",
|
"refreshJwt": "alice-refresh-jwt-2",
|
||||||
"service": "https://alice.com/",
|
"service": "https://alice.com/",
|
||||||
"signupQueued": false,
|
"signupQueued": false,
|
||||||
"status": "active",
|
"status": undefined,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"currentAgentState": {
|
"currentAgentState": {
|
||||||
@@ -720,6 +749,7 @@ describe('session', () => {
|
|||||||
`)
|
`)
|
||||||
|
|
||||||
agent1.session = {
|
agent1.session = {
|
||||||
|
active: true,
|
||||||
did: 'alice-did',
|
did: 'alice-did',
|
||||||
handle: 'alice-updated.test',
|
handle: 'alice-updated.test',
|
||||||
accessJwt: 'alice-access-jwt-3',
|
accessJwt: 'alice-access-jwt-3',
|
||||||
@@ -748,6 +778,7 @@ describe('session', () => {
|
|||||||
"accounts": [
|
"accounts": [
|
||||||
{
|
{
|
||||||
"accessJwt": "alice-access-jwt-3",
|
"accessJwt": "alice-access-jwt-3",
|
||||||
|
"active": true,
|
||||||
"did": "alice-did",
|
"did": "alice-did",
|
||||||
"email": "alice@foo.baz",
|
"email": "alice@foo.baz",
|
||||||
"emailAuthFactor": true,
|
"emailAuthFactor": true,
|
||||||
@@ -757,7 +788,7 @@ describe('session', () => {
|
|||||||
"refreshJwt": "alice-refresh-jwt-3",
|
"refreshJwt": "alice-refresh-jwt-3",
|
||||||
"service": "https://alice.com/",
|
"service": "https://alice.com/",
|
||||||
"signupQueued": false,
|
"signupQueued": false,
|
||||||
"status": "active",
|
"status": undefined,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"currentAgentState": {
|
"currentAgentState": {
|
||||||
@@ -771,6 +802,7 @@ describe('session', () => {
|
|||||||
`)
|
`)
|
||||||
|
|
||||||
agent1.session = {
|
agent1.session = {
|
||||||
|
active: true,
|
||||||
did: 'alice-did',
|
did: 'alice-did',
|
||||||
handle: 'alice-updated.test',
|
handle: 'alice-updated.test',
|
||||||
accessJwt: 'alice-access-jwt-4',
|
accessJwt: 'alice-access-jwt-4',
|
||||||
@@ -799,6 +831,7 @@ describe('session', () => {
|
|||||||
"accounts": [
|
"accounts": [
|
||||||
{
|
{
|
||||||
"accessJwt": "alice-access-jwt-4",
|
"accessJwt": "alice-access-jwt-4",
|
||||||
|
"active": true,
|
||||||
"did": "alice-did",
|
"did": "alice-did",
|
||||||
"email": "alice@foo.baz",
|
"email": "alice@foo.baz",
|
||||||
"emailAuthFactor": false,
|
"emailAuthFactor": false,
|
||||||
@@ -808,7 +841,7 @@ describe('session', () => {
|
|||||||
"refreshJwt": "alice-refresh-jwt-4",
|
"refreshJwt": "alice-refresh-jwt-4",
|
||||||
"service": "https://alice.com/",
|
"service": "https://alice.com/",
|
||||||
"signupQueued": false,
|
"signupQueued": false,
|
||||||
"status": "active",
|
"status": undefined,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"currentAgentState": {
|
"currentAgentState": {
|
||||||
@@ -827,6 +860,7 @@ describe('session', () => {
|
|||||||
|
|
||||||
const agent1 = new BskyAgent({service: 'https://alice.com'})
|
const agent1 = new BskyAgent({service: 'https://alice.com'})
|
||||||
agent1.session = {
|
agent1.session = {
|
||||||
|
active: true,
|
||||||
did: 'alice-did',
|
did: 'alice-did',
|
||||||
handle: 'alice.test',
|
handle: 'alice.test',
|
||||||
accessJwt: 'alice-access-jwt-1',
|
accessJwt: 'alice-access-jwt-1',
|
||||||
@@ -843,6 +877,7 @@ describe('session', () => {
|
|||||||
expect(state.currentAgentState.did).toBe('alice-did')
|
expect(state.currentAgentState.did).toBe('alice-did')
|
||||||
|
|
||||||
agent1.session = {
|
agent1.session = {
|
||||||
|
active: true,
|
||||||
did: 'alice-did',
|
did: 'alice-did',
|
||||||
handle: 'alice-updated.test',
|
handle: 'alice-updated.test',
|
||||||
accessJwt: 'alice-access-jwt-2',
|
accessJwt: 'alice-access-jwt-2',
|
||||||
@@ -873,6 +908,7 @@ describe('session', () => {
|
|||||||
expect(lastState === state).toBe(true)
|
expect(lastState === state).toBe(true)
|
||||||
|
|
||||||
agent1.session = {
|
agent1.session = {
|
||||||
|
active: true,
|
||||||
did: 'alice-did',
|
did: 'alice-did',
|
||||||
handle: 'alice-updated.test',
|
handle: 'alice-updated.test',
|
||||||
accessJwt: 'alice-access-jwt-3',
|
accessJwt: 'alice-access-jwt-3',
|
||||||
@@ -896,6 +932,7 @@ describe('session', () => {
|
|||||||
|
|
||||||
const agent1 = new BskyAgent({service: 'https://alice.com'})
|
const agent1 = new BskyAgent({service: 'https://alice.com'})
|
||||||
agent1.session = {
|
agent1.session = {
|
||||||
|
active: true,
|
||||||
did: 'alice-did',
|
did: 'alice-did',
|
||||||
handle: 'alice.test',
|
handle: 'alice.test',
|
||||||
accessJwt: 'alice-access-jwt-1',
|
accessJwt: 'alice-access-jwt-1',
|
||||||
@@ -904,6 +941,7 @@ describe('session', () => {
|
|||||||
|
|
||||||
const agent2 = new BskyAgent({service: 'https://bob.com'})
|
const agent2 = new BskyAgent({service: 'https://bob.com'})
|
||||||
agent2.session = {
|
agent2.session = {
|
||||||
|
active: true,
|
||||||
did: 'bob-did',
|
did: 'bob-did',
|
||||||
handle: 'bob.test',
|
handle: 'bob.test',
|
||||||
accessJwt: 'bob-access-jwt-1',
|
accessJwt: 'bob-access-jwt-1',
|
||||||
@@ -928,6 +966,7 @@ describe('session', () => {
|
|||||||
expect(state.currentAgentState.did).toBe('bob-did')
|
expect(state.currentAgentState.did).toBe('bob-did')
|
||||||
|
|
||||||
agent1.session = {
|
agent1.session = {
|
||||||
|
active: true,
|
||||||
did: 'alice-did',
|
did: 'alice-did',
|
||||||
handle: 'alice-updated.test',
|
handle: 'alice-updated.test',
|
||||||
accessJwt: 'alice-access-jwt-2',
|
accessJwt: 'alice-access-jwt-2',
|
||||||
@@ -956,6 +995,7 @@ describe('session', () => {
|
|||||||
"accounts": [
|
"accounts": [
|
||||||
{
|
{
|
||||||
"accessJwt": "bob-access-jwt-1",
|
"accessJwt": "bob-access-jwt-1",
|
||||||
|
"active": true,
|
||||||
"did": "bob-did",
|
"did": "bob-did",
|
||||||
"email": undefined,
|
"email": undefined,
|
||||||
"emailAuthFactor": false,
|
"emailAuthFactor": false,
|
||||||
@@ -965,10 +1005,11 @@ describe('session', () => {
|
|||||||
"refreshJwt": "bob-refresh-jwt-1",
|
"refreshJwt": "bob-refresh-jwt-1",
|
||||||
"service": "https://bob.com/",
|
"service": "https://bob.com/",
|
||||||
"signupQueued": false,
|
"signupQueued": false,
|
||||||
"status": "active",
|
"status": undefined,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"accessJwt": "alice-access-jwt-2",
|
"accessJwt": "alice-access-jwt-2",
|
||||||
|
"active": true,
|
||||||
"did": "alice-did",
|
"did": "alice-did",
|
||||||
"email": "alice@foo.bar",
|
"email": "alice@foo.bar",
|
||||||
"emailAuthFactor": false,
|
"emailAuthFactor": false,
|
||||||
@@ -978,7 +1019,7 @@ describe('session', () => {
|
|||||||
"refreshJwt": "alice-refresh-jwt-2",
|
"refreshJwt": "alice-refresh-jwt-2",
|
||||||
"service": "https://alice.com/",
|
"service": "https://alice.com/",
|
||||||
"signupQueued": false,
|
"signupQueued": false,
|
||||||
"status": "active",
|
"status": undefined,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"currentAgentState": {
|
"currentAgentState": {
|
||||||
@@ -992,6 +1033,7 @@ describe('session', () => {
|
|||||||
`)
|
`)
|
||||||
|
|
||||||
agent2.session = {
|
agent2.session = {
|
||||||
|
active: true,
|
||||||
did: 'bob-did',
|
did: 'bob-did',
|
||||||
handle: 'bob-updated.test',
|
handle: 'bob-updated.test',
|
||||||
accessJwt: 'bob-access-jwt-2',
|
accessJwt: 'bob-access-jwt-2',
|
||||||
@@ -1018,6 +1060,7 @@ describe('session', () => {
|
|||||||
"accounts": [
|
"accounts": [
|
||||||
{
|
{
|
||||||
"accessJwt": "bob-access-jwt-2",
|
"accessJwt": "bob-access-jwt-2",
|
||||||
|
"active": true,
|
||||||
"did": "bob-did",
|
"did": "bob-did",
|
||||||
"email": undefined,
|
"email": undefined,
|
||||||
"emailAuthFactor": false,
|
"emailAuthFactor": false,
|
||||||
@@ -1027,10 +1070,11 @@ describe('session', () => {
|
|||||||
"refreshJwt": "bob-refresh-jwt-2",
|
"refreshJwt": "bob-refresh-jwt-2",
|
||||||
"service": "https://bob.com/",
|
"service": "https://bob.com/",
|
||||||
"signupQueued": false,
|
"signupQueued": false,
|
||||||
"status": "active",
|
"status": undefined,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"accessJwt": "alice-access-jwt-2",
|
"accessJwt": "alice-access-jwt-2",
|
||||||
|
"active": true,
|
||||||
"did": "alice-did",
|
"did": "alice-did",
|
||||||
"email": "alice@foo.bar",
|
"email": "alice@foo.bar",
|
||||||
"emailAuthFactor": false,
|
"emailAuthFactor": false,
|
||||||
@@ -1040,7 +1084,7 @@ describe('session', () => {
|
|||||||
"refreshJwt": "alice-refresh-jwt-2",
|
"refreshJwt": "alice-refresh-jwt-2",
|
||||||
"service": "https://alice.com/",
|
"service": "https://alice.com/",
|
||||||
"signupQueued": false,
|
"signupQueued": false,
|
||||||
"status": "active",
|
"status": undefined,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"currentAgentState": {
|
"currentAgentState": {
|
||||||
@@ -1083,6 +1127,7 @@ describe('session', () => {
|
|||||||
|
|
||||||
const agent1 = new BskyAgent({service: 'https://alice.com'})
|
const agent1 = new BskyAgent({service: 'https://alice.com'})
|
||||||
agent1.session = {
|
agent1.session = {
|
||||||
|
active: true,
|
||||||
did: 'alice-did',
|
did: 'alice-did',
|
||||||
handle: 'alice.test',
|
handle: 'alice.test',
|
||||||
accessJwt: 'alice-access-jwt-1',
|
accessJwt: 'alice-access-jwt-1',
|
||||||
@@ -1091,6 +1136,7 @@ describe('session', () => {
|
|||||||
|
|
||||||
const agent2 = new BskyAgent({service: 'https://bob.com'})
|
const agent2 = new BskyAgent({service: 'https://bob.com'})
|
||||||
agent2.session = {
|
agent2.session = {
|
||||||
|
active: true,
|
||||||
did: 'bob-did',
|
did: 'bob-did',
|
||||||
handle: 'bob.test',
|
handle: 'bob.test',
|
||||||
accessJwt: 'bob-access-jwt-1',
|
accessJwt: 'bob-access-jwt-1',
|
||||||
@@ -1117,6 +1163,7 @@ describe('session', () => {
|
|||||||
expect(state.currentAgentState.did).toBe('bob-did')
|
expect(state.currentAgentState.did).toBe('bob-did')
|
||||||
|
|
||||||
agent1.session = {
|
agent1.session = {
|
||||||
|
active: true,
|
||||||
did: 'alice-did',
|
did: 'alice-did',
|
||||||
handle: 'alice.test',
|
handle: 'alice.test',
|
||||||
accessJwt: 'alice-access-jwt-2',
|
accessJwt: 'alice-access-jwt-2',
|
||||||
@@ -1142,6 +1189,7 @@ describe('session', () => {
|
|||||||
|
|
||||||
const agent1 = new BskyAgent({service: 'https://alice.com'})
|
const agent1 = new BskyAgent({service: 'https://alice.com'})
|
||||||
agent1.session = {
|
agent1.session = {
|
||||||
|
active: true,
|
||||||
did: 'alice-did',
|
did: 'alice-did',
|
||||||
handle: 'alice.test',
|
handle: 'alice.test',
|
||||||
accessJwt: 'alice-access-jwt-1',
|
accessJwt: 'alice-access-jwt-1',
|
||||||
@@ -1179,6 +1227,7 @@ describe('session', () => {
|
|||||||
"accounts": [
|
"accounts": [
|
||||||
{
|
{
|
||||||
"accessJwt": "alice-access-jwt-1",
|
"accessJwt": "alice-access-jwt-1",
|
||||||
|
"active": true,
|
||||||
"did": "alice-did",
|
"did": "alice-did",
|
||||||
"email": undefined,
|
"email": undefined,
|
||||||
"emailAuthFactor": false,
|
"emailAuthFactor": false,
|
||||||
@@ -1188,7 +1237,7 @@ describe('session', () => {
|
|||||||
"refreshJwt": "alice-refresh-jwt-1",
|
"refreshJwt": "alice-refresh-jwt-1",
|
||||||
"service": "https://alice.com/",
|
"service": "https://alice.com/",
|
||||||
"signupQueued": false,
|
"signupQueued": false,
|
||||||
"status": "active",
|
"status": undefined,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"currentAgentState": {
|
"currentAgentState": {
|
||||||
@@ -1207,6 +1256,7 @@ describe('session', () => {
|
|||||||
|
|
||||||
const agent1 = new BskyAgent({service: 'https://alice.com'})
|
const agent1 = new BskyAgent({service: 'https://alice.com'})
|
||||||
agent1.session = {
|
agent1.session = {
|
||||||
|
active: true,
|
||||||
did: 'alice-did',
|
did: 'alice-did',
|
||||||
handle: 'alice.test',
|
handle: 'alice.test',
|
||||||
accessJwt: 'alice-access-jwt-1',
|
accessJwt: 'alice-access-jwt-1',
|
||||||
@@ -1242,6 +1292,7 @@ describe('session', () => {
|
|||||||
"accounts": [
|
"accounts": [
|
||||||
{
|
{
|
||||||
"accessJwt": undefined,
|
"accessJwt": undefined,
|
||||||
|
"active": true,
|
||||||
"did": "alice-did",
|
"did": "alice-did",
|
||||||
"email": undefined,
|
"email": undefined,
|
||||||
"emailAuthFactor": false,
|
"emailAuthFactor": false,
|
||||||
@@ -1251,7 +1302,7 @@ describe('session', () => {
|
|||||||
"refreshJwt": undefined,
|
"refreshJwt": undefined,
|
||||||
"service": "https://alice.com/",
|
"service": "https://alice.com/",
|
||||||
"signupQueued": false,
|
"signupQueued": false,
|
||||||
"status": "active",
|
"status": undefined,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"currentAgentState": {
|
"currentAgentState": {
|
||||||
@@ -1270,6 +1321,7 @@ describe('session', () => {
|
|||||||
|
|
||||||
const agent1 = new BskyAgent({service: 'https://alice.com'})
|
const agent1 = new BskyAgent({service: 'https://alice.com'})
|
||||||
agent1.session = {
|
agent1.session = {
|
||||||
|
active: true,
|
||||||
did: 'alice-did',
|
did: 'alice-did',
|
||||||
handle: 'alice.test',
|
handle: 'alice.test',
|
||||||
accessJwt: 'alice-access-jwt-1',
|
accessJwt: 'alice-access-jwt-1',
|
||||||
@@ -1305,6 +1357,7 @@ describe('session', () => {
|
|||||||
"accounts": [
|
"accounts": [
|
||||||
{
|
{
|
||||||
"accessJwt": undefined,
|
"accessJwt": undefined,
|
||||||
|
"active": true,
|
||||||
"did": "alice-did",
|
"did": "alice-did",
|
||||||
"email": undefined,
|
"email": undefined,
|
||||||
"emailAuthFactor": false,
|
"emailAuthFactor": false,
|
||||||
@@ -1314,7 +1367,7 @@ describe('session', () => {
|
|||||||
"refreshJwt": undefined,
|
"refreshJwt": undefined,
|
||||||
"service": "https://alice.com/",
|
"service": "https://alice.com/",
|
||||||
"signupQueued": false,
|
"signupQueued": false,
|
||||||
"status": "active",
|
"status": undefined,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"currentAgentState": {
|
"currentAgentState": {
|
||||||
@@ -1333,6 +1386,7 @@ describe('session', () => {
|
|||||||
|
|
||||||
const agent1 = new BskyAgent({service: 'https://alice.com'})
|
const agent1 = new BskyAgent({service: 'https://alice.com'})
|
||||||
agent1.session = {
|
agent1.session = {
|
||||||
|
active: true,
|
||||||
did: 'alice-did',
|
did: 'alice-did',
|
||||||
handle: 'alice.test',
|
handle: 'alice.test',
|
||||||
accessJwt: 'alice-access-jwt-1',
|
accessJwt: 'alice-access-jwt-1',
|
||||||
@@ -1340,6 +1394,7 @@ describe('session', () => {
|
|||||||
}
|
}
|
||||||
const agent2 = new BskyAgent({service: 'https://bob.com'})
|
const agent2 = new BskyAgent({service: 'https://bob.com'})
|
||||||
agent2.session = {
|
agent2.session = {
|
||||||
|
active: true,
|
||||||
did: 'bob-did',
|
did: 'bob-did',
|
||||||
handle: 'bob.test',
|
handle: 'bob.test',
|
||||||
accessJwt: 'bob-access-jwt-1',
|
accessJwt: 'bob-access-jwt-1',
|
||||||
@@ -1362,6 +1417,7 @@ describe('session', () => {
|
|||||||
|
|
||||||
const anotherTabAgent1 = new BskyAgent({service: 'https://jay.com'})
|
const anotherTabAgent1 = new BskyAgent({service: 'https://jay.com'})
|
||||||
anotherTabAgent1.session = {
|
anotherTabAgent1.session = {
|
||||||
|
active: true,
|
||||||
did: 'jay-did',
|
did: 'jay-did',
|
||||||
handle: 'jay.test',
|
handle: 'jay.test',
|
||||||
accessJwt: 'jay-access-jwt-1',
|
accessJwt: 'jay-access-jwt-1',
|
||||||
@@ -1369,6 +1425,7 @@ describe('session', () => {
|
|||||||
}
|
}
|
||||||
const anotherTabAgent2 = new BskyAgent({service: 'https://alice.com'})
|
const anotherTabAgent2 = new BskyAgent({service: 'https://alice.com'})
|
||||||
anotherTabAgent2.session = {
|
anotherTabAgent2.session = {
|
||||||
|
active: true,
|
||||||
did: 'bob-did',
|
did: 'bob-did',
|
||||||
handle: 'bob.test',
|
handle: 'bob.test',
|
||||||
accessJwt: 'bob-access-jwt-2',
|
accessJwt: 'bob-access-jwt-2',
|
||||||
@@ -1397,6 +1454,7 @@ describe('session', () => {
|
|||||||
"accounts": [
|
"accounts": [
|
||||||
{
|
{
|
||||||
"accessJwt": "jay-access-jwt-1",
|
"accessJwt": "jay-access-jwt-1",
|
||||||
|
"active": true,
|
||||||
"did": "jay-did",
|
"did": "jay-did",
|
||||||
"email": undefined,
|
"email": undefined,
|
||||||
"emailAuthFactor": false,
|
"emailAuthFactor": false,
|
||||||
@@ -1406,10 +1464,11 @@ describe('session', () => {
|
|||||||
"refreshJwt": "jay-refresh-jwt-1",
|
"refreshJwt": "jay-refresh-jwt-1",
|
||||||
"service": "https://jay.com/",
|
"service": "https://jay.com/",
|
||||||
"signupQueued": false,
|
"signupQueued": false,
|
||||||
"status": "active",
|
"status": undefined,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"accessJwt": "bob-access-jwt-2",
|
"accessJwt": "bob-access-jwt-2",
|
||||||
|
"active": true,
|
||||||
"did": "bob-did",
|
"did": "bob-did",
|
||||||
"email": undefined,
|
"email": undefined,
|
||||||
"emailAuthFactor": false,
|
"emailAuthFactor": false,
|
||||||
@@ -1419,7 +1478,7 @@ describe('session', () => {
|
|||||||
"refreshJwt": "bob-refresh-jwt-2",
|
"refreshJwt": "bob-refresh-jwt-2",
|
||||||
"service": "https://alice.com/",
|
"service": "https://alice.com/",
|
||||||
"signupQueued": false,
|
"signupQueued": false,
|
||||||
"status": "active",
|
"status": undefined,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"currentAgentState": {
|
"currentAgentState": {
|
||||||
@@ -1434,6 +1493,7 @@ describe('session', () => {
|
|||||||
|
|
||||||
const anotherTabAgent3 = new BskyAgent({service: 'https://clarence.com'})
|
const anotherTabAgent3 = new BskyAgent({service: 'https://clarence.com'})
|
||||||
anotherTabAgent3.session = {
|
anotherTabAgent3.session = {
|
||||||
|
active: true,
|
||||||
did: 'clarence-did',
|
did: 'clarence-did',
|
||||||
handle: 'clarence.test',
|
handle: 'clarence.test',
|
||||||
accessJwt: 'clarence-access-jwt-2',
|
accessJwt: 'clarence-access-jwt-2',
|
||||||
@@ -1457,6 +1517,7 @@ describe('session', () => {
|
|||||||
"accounts": [
|
"accounts": [
|
||||||
{
|
{
|
||||||
"accessJwt": "clarence-access-jwt-2",
|
"accessJwt": "clarence-access-jwt-2",
|
||||||
|
"active": true,
|
||||||
"did": "clarence-did",
|
"did": "clarence-did",
|
||||||
"email": undefined,
|
"email": undefined,
|
||||||
"emailAuthFactor": false,
|
"emailAuthFactor": false,
|
||||||
@@ -1466,7 +1527,7 @@ describe('session', () => {
|
|||||||
"refreshJwt": "clarence-refresh-jwt-2",
|
"refreshJwt": "clarence-refresh-jwt-2",
|
||||||
"service": "https://clarence.com/",
|
"service": "https://clarence.com/",
|
||||||
"signupQueued": false,
|
"signupQueued": false,
|
||||||
"status": "active",
|
"status": undefined,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"currentAgentState": {
|
"currentAgentState": {
|
||||||
|
|||||||
@@ -46,6 +46,11 @@ export async function createAgentAndResume(
|
|||||||
emailConfirmed: storedAccount.emailConfirmed,
|
emailConfirmed: storedAccount.emailConfirmed,
|
||||||
handle: storedAccount.handle,
|
handle: storedAccount.handle,
|
||||||
refreshJwt: storedAccount.refreshJwt ?? '',
|
refreshJwt: storedAccount.refreshJwt ?? '',
|
||||||
|
/**
|
||||||
|
* @see https://github.com/bluesky-social/atproto/blob/c5d36d5ba2a2c2a5c4f366a5621c06a5608e361e/packages/api/src/agent.ts#L188
|
||||||
|
*/
|
||||||
|
active: storedAccount.active ?? true,
|
||||||
|
status: storedAccount.status,
|
||||||
}
|
}
|
||||||
if (isSessionExpired(storedAccount)) {
|
if (isSessionExpired(storedAccount)) {
|
||||||
await networkRetry(1, () => agent.resumeSession(prevSession))
|
await networkRetry(1, () => agent.resumeSession(prevSession))
|
||||||
@@ -235,8 +240,8 @@ export function agentToSessionAccount(
|
|||||||
refreshJwt: agent.session.refreshJwt,
|
refreshJwt: agent.session.refreshJwt,
|
||||||
accessJwt: agent.session.accessJwt,
|
accessJwt: agent.session.accessJwt,
|
||||||
signupQueued: isSignupQueued(agent.session.accessJwt),
|
signupQueued: isSignupQueued(agent.session.accessJwt),
|
||||||
// @ts-expect-error TODO remove when backend is ready
|
active: agent.session.active,
|
||||||
status: agent.session.status || 'active',
|
status: agent.session.status as SessionAccount['status'],
|
||||||
pdsUrl: agent.pdsUrl?.toString(),
|
pdsUrl: agent.pdsUrl?.toString(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -154,6 +154,13 @@ export const ComposePost = observer(function ComposePost({
|
|||||||
const [extGif, setExtGif] = useState<Gif>()
|
const [extGif, setExtGif] = useState<Gif>()
|
||||||
const [labels, setLabels] = useState<string[]>([])
|
const [labels, setLabels] = useState<string[]>([])
|
||||||
const [threadgate, setThreadgate] = useState<ThreadgateSetting[]>([])
|
const [threadgate, setThreadgate] = useState<ThreadgateSetting[]>([])
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (!isAndroid) return
|
||||||
|
const id = setTimeout(() => textInput.current?.focus(), 100)
|
||||||
|
return () => clearTimeout(id)
|
||||||
|
}, [])
|
||||||
|
|
||||||
const gallery = useMemo(
|
const gallery = useMemo(
|
||||||
() => new GalleryModel(initImageUris),
|
() => new GalleryModel(initImageUris),
|
||||||
[initImageUris],
|
[initImageUris],
|
||||||
@@ -517,7 +524,7 @@ export const ComposePost = observer(function ComposePost({
|
|||||||
ref={textInput}
|
ref={textInput}
|
||||||
richtext={richtext}
|
richtext={richtext}
|
||||||
placeholder={selectTextInputPlaceholder}
|
placeholder={selectTextInputPlaceholder}
|
||||||
autoFocus={true}
|
autoFocus={!isAndroid}
|
||||||
setRichText={setRichText}
|
setRichText={setRichText}
|
||||||
onPhotoPasted={onPhotoPasted}
|
onPhotoPasted={onPhotoPasted}
|
||||||
onPressPublish={onPressPublish}
|
onPressPublish={onPressPublish}
|
||||||
|
|||||||
@@ -161,7 +161,11 @@ export function Feed({
|
|||||||
)
|
)
|
||||||
} else if (item === LOADING_ITEM) {
|
} else if (item === LOADING_ITEM) {
|
||||||
return (
|
return (
|
||||||
<View style={[pal.border, {borderTopWidth: hairlineWidth}]}>
|
<View
|
||||||
|
style={[
|
||||||
|
pal.border,
|
||||||
|
!isTabletOrMobile && {borderTopWidth: hairlineWidth},
|
||||||
|
]}>
|
||||||
<NotificationFeedLoadingPlaceholder />
|
<NotificationFeedLoadingPlaceholder />
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
@@ -217,6 +221,7 @@ export function Feed({
|
|||||||
desktopFixedHeight
|
desktopFixedHeight
|
||||||
initialNumToRender={initialNumToRender}
|
initialNumToRender={initialNumToRender}
|
||||||
windowSize={11}
|
windowSize={11}
|
||||||
|
sideBorders={false}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -108,6 +108,7 @@ let RepostButton = ({
|
|||||||
</Text>
|
</Text>
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
|
testID="quoteBtn"
|
||||||
style={[a.justify_start, a.px_md]}
|
style={[a.justify_start, a.px_md]}
|
||||||
label={_(msg`Quote post`)}
|
label={_(msg`Quote post`)}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
|
|||||||
@@ -181,9 +181,11 @@ export function QuoteEmbed({
|
|||||||
}, [queryClient, quote.author, onOpen])
|
}, [queryClient, quote.author, onOpen])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ContentHider modui={moderation?.ui('contentList')}>
|
<ContentHider
|
||||||
|
modui={moderation?.ui('contentList')}
|
||||||
|
style={[styles.container, pal.borderDark, style]}
|
||||||
|
childContainerStyle={[a.pt_sm]}>
|
||||||
<Link
|
<Link
|
||||||
style={[styles.container, pal.borderDark, style]}
|
|
||||||
hoverStyle={{borderColor: pal.colors.borderLinkHover}}
|
hoverStyle={{borderColor: pal.colors.borderLinkHover}}
|
||||||
href={itemHref}
|
href={itemHref}
|
||||||
title={itemTitle}
|
title={itemTitle}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import {colors, s} from 'lib/styles'
|
|||||||
import {TextLink} from 'view/com/util/Link'
|
import {TextLink} from 'view/com/util/Link'
|
||||||
import {ListMethods} from 'view/com/util/List'
|
import {ListMethods} from 'view/com/util/List'
|
||||||
import {LoadLatestBtn} from 'view/com/util/load-latest/LoadLatestBtn'
|
import {LoadLatestBtn} from 'view/com/util/load-latest/LoadLatestBtn'
|
||||||
|
import {CenteredView} from 'view/com/util/Views'
|
||||||
import {Feed} from '../com/notifications/Feed'
|
import {Feed} from '../com/notifications/Feed'
|
||||||
import {FAB} from '../com/util/fab/FAB'
|
import {FAB} from '../com/util/fab/FAB'
|
||||||
import {MainScrollProvider} from '../com/util/MainScrollProvider'
|
import {MainScrollProvider} from '../com/util/MainScrollProvider'
|
||||||
@@ -145,7 +146,10 @@ export function NotificationsScreen({}: Props) {
|
|||||||
}, [isDesktop, pal, hasNew])
|
}, [isDesktop, pal, hasNew])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View testID="notificationsScreen" style={s.hContentRegion}>
|
<CenteredView
|
||||||
|
testID="notificationsScreen"
|
||||||
|
style={s.hContentRegion}
|
||||||
|
sideBorders={true}>
|
||||||
<ViewHeader
|
<ViewHeader
|
||||||
title={_(msg`Notifications`)}
|
title={_(msg`Notifications`)}
|
||||||
canGoBack={false}
|
canGoBack={false}
|
||||||
@@ -173,6 +177,6 @@ export function NotificationsScreen({}: Props) {
|
|||||||
accessibilityLabel={_(msg`New post`)}
|
accessibilityLabel={_(msg`New post`)}
|
||||||
accessibilityHint=""
|
accessibilityHint=""
|
||||||
/>
|
/>
|
||||||
</View>
|
</CenteredView>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import {NoFollowingFeed} from '#/screens/Feeds/NoFollowingFeed'
|
|||||||
import {NoSavedFeedsOfAnyType} from '#/screens/Feeds/NoSavedFeedsOfAnyType'
|
import {NoSavedFeedsOfAnyType} from '#/screens/Feeds/NoSavedFeedsOfAnyType'
|
||||||
import {atoms as a, useTheme} from '#/alf'
|
import {atoms as a, useTheme} from '#/alf'
|
||||||
import {FilterTimeline_Stroke2_Corner0_Rounded as FilterTimeline} from '#/components/icons/FilterTimeline'
|
import {FilterTimeline_Stroke2_Corner0_Rounded as FilterTimeline} from '#/components/icons/FilterTimeline'
|
||||||
|
import hairlineWidth = StyleSheet.hairlineWidth
|
||||||
|
|
||||||
const HITSLOP_TOP = {
|
const HITSLOP_TOP = {
|
||||||
top: 20,
|
top: 20,
|
||||||
@@ -92,7 +93,7 @@ export function SavedFeeds({}: Props) {
|
|||||||
<ViewHeader title={_(msg`Edit My Feeds`)} showOnDesktop showBorder />
|
<ViewHeader title={_(msg`Edit My Feeds`)} showOnDesktop showBorder />
|
||||||
<ScrollView style={s.flex1} contentContainerStyle={[styles.noBorder]}>
|
<ScrollView style={s.flex1} contentContainerStyle={[styles.noBorder]}>
|
||||||
{noSavedFeedsOfAnyType && (
|
{noSavedFeedsOfAnyType && (
|
||||||
<View style={[pal.border, {borderBottomWidth: 1}]}>
|
<View style={[pal.border, {borderBottomWidth: hairlineWidth}]}>
|
||||||
<NoSavedFeedsOfAnyType />
|
<NoSavedFeedsOfAnyType />
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
@@ -134,7 +135,7 @@ export function SavedFeeds({}: Props) {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{noFollowingFeed && (
|
{noFollowingFeed && (
|
||||||
<View style={[pal.border, {borderBottomWidth: 1}]}>
|
<View style={[pal.border, {borderBottomWidth: hairlineWidth}]}>
|
||||||
<NoFollowingFeed />
|
<NoFollowingFeed />
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
@@ -298,9 +299,10 @@ function ListItem({
|
|||||||
<FeedSourceCard
|
<FeedSourceCard
|
||||||
key={feedUri}
|
key={feedUri}
|
||||||
feedUri={feedUri}
|
feedUri={feedUri}
|
||||||
style={[styles.noTopBorder, isPinned && {paddingRight: 8}]}
|
style={[isPinned && {paddingRight: 8}]}
|
||||||
showMinimalPlaceholder
|
showMinimalPlaceholder
|
||||||
showSaveBtn={!isPinned}
|
showSaveBtn={!isPinned}
|
||||||
|
hideTopBorder={true}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{isPinned ? (
|
{isPinned ? (
|
||||||
@@ -435,15 +437,12 @@ const styles = StyleSheet.create({
|
|||||||
paddingHorizontal: 14,
|
paddingHorizontal: 14,
|
||||||
paddingTop: 20,
|
paddingTop: 20,
|
||||||
paddingBottom: 10,
|
paddingBottom: 10,
|
||||||
borderBottomWidth: 1,
|
borderBottomWidth: hairlineWidth,
|
||||||
},
|
},
|
||||||
itemContainer: {
|
itemContainer: {
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
borderBottomWidth: 1,
|
borderBottomWidth: hairlineWidth,
|
||||||
},
|
|
||||||
noTopBorder: {
|
|
||||||
borderTopWidth: 0,
|
|
||||||
},
|
},
|
||||||
footerText: {
|
footerText: {
|
||||||
paddingHorizontal: 26,
|
paddingHorizontal: 26,
|
||||||
|
|||||||
@@ -34,10 +34,10 @@
|
|||||||
jsonpointer "^5.0.0"
|
jsonpointer "^5.0.0"
|
||||||
leven "^3.1.0"
|
leven "^3.1.0"
|
||||||
|
|
||||||
"@atproto/api@^0.12.14":
|
"@atproto/api@^0.12.16":
|
||||||
version "0.12.14"
|
version "0.12.16"
|
||||||
resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.12.14.tgz#81252fd166ec8fe950056531e690d563437720fa"
|
resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.12.16.tgz#f5b5e06d75d379dafe79521d727ed8ad5516d3fc"
|
||||||
integrity sha512-ZPh/afoRjFEQDQgMZW2FQiG5CDUifY7SxBqI0zVJUwed8Zi6fqYzGYM8fcDvD8yJfflRCqRxUE72g5fKiA1zAQ==
|
integrity sha512-v3lA/m17nkawDXiqgwXyaUSzJPeXJBMH8QKOoYxcDqN+8yG9LFlGe2ecGarXcbGQjYT0GJTAAW3Y/AaCOEwuLg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@atproto/common-web" "^0.3.0"
|
"@atproto/common-web" "^0.3.0"
|
||||||
"@atproto/lexicon" "^0.4.0"
|
"@atproto/lexicon" "^0.4.0"
|
||||||
|
|||||||
Reference in New Issue
Block a user