diff --git a/.github/workflows/mobile-build-nightly.yml b/.github/workflows/mobile-build-nightly.yml
new file mode 100644
index 0000000000..3ba4f57436
--- /dev/null
+++ b/.github/workflows/mobile-build-nightly.yml
@@ -0,0 +1,52 @@
+name: Build Tlon Mobile Nightly
+on:
+ schedule:
+ - cron: "0 8 * * *"
+
+jobs:
+ deploy:
+ runs-on: ubuntu-latest
+ name: Create mobile builds
+ steps:
+ - name: Check out repository
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+ - name: Check for changes in develop
+ id: changes
+ run: |
+ git fetch origin develop
+ if [ $(git rev-list --since="24 hours ago" origin/develop --count) -eq 0 ]; then
+ echo "No changes in develop in the past 24 hours"
+ echo "::set-output name=changes::0"
+ exit 0
+ else
+ echo "::set-output name=changes::1"
+ fi
+ - name: Set up Node.js
+ if: steps.changes.outputs.changes != '0'
+ uses: actions/setup-node@v4
+ with:
+ node-version-file: .nvmrc
+ - name: Set up Expo and EAS
+ if: steps.changes.outputs.changes != '0'
+ uses: expo/expo-github-action@v8
+ with:
+ eas-version: latest
+ token: ${{ secrets.EXPO_TOKEN }}
+ - name: Setup PNPM
+ if: steps.changes.outputs.changes != '0'
+ uses: pnpm/action-setup@v3
+ - name: Install dependencies
+ if: steps.changes.outputs.changes != '0'
+ run: pnpm install --frozen-lockfile
+ - name: Build for selected platforms
+ if: steps.changes.outputs.changes != '0'
+ working-directory: ./apps/tlon-mobile
+ run: |
+ eas build --profile preview --platform all --non-interactive --auto-submit
+ env:
+ EXPO_APPLE_ID: ${{ secrets.EXPO_APPLE_ID }}
+ EXPO_APPLE_PASSWORD: ${{ secrets.EXPO_APPLE_PASSWORD }}
+ NOTIFY_PROVIDER: "binnec-dozzod-marnus"
+ NOTIFY_SERVICE: "tlon-preview-release"
diff --git a/apps/tlon-mobile/.env.sample b/apps/tlon-mobile/.env.sample
index 7141de8b6f..2f3f03903a 100644
--- a/apps/tlon-mobile/.env.sample
+++ b/apps/tlon-mobile/.env.sample
@@ -6,6 +6,7 @@ NOTIFY_SERVICE=tlon-preview-debug
# Prefills auth flow for quicker logins
DEFAULT_TLON_LOGIN_EMAIL=
DEFAULT_TLON_LOGIN_PASSWORD=
+DEFAULT_INVITE_LINK_URL=
DEFAULT_SHIP_LOGIN_URL=
DEFAULT_SHIP_LOGIN_ACCESS_CODE=
diff --git a/apps/tlon-mobile/README.md b/apps/tlon-mobile/README.md
index d2abc94a82..667511662d 100644
--- a/apps/tlon-mobile/README.md
+++ b/apps/tlon-mobile/README.md
@@ -115,6 +115,7 @@ To streamline testing the login flow, you can use env variables to prepopulate f
```
DEFAULT_TLON_LOGIN_EMAIL=
DEFAULT_TLON_LOGIN_PASSWORD=
+DEFAULT_INVITE_LINK_URL=
DEFAULT_SHIP_LOGIN_URL=
DEFAULT_SHIP_LOGIN_ACCESS_CODE=
```
diff --git a/apps/tlon-mobile/android/app/build.gradle b/apps/tlon-mobile/android/app/build.gradle
index 8572d5c316..6603e28a5f 100644
--- a/apps/tlon-mobile/android/app/build.gradle
+++ b/apps/tlon-mobile/android/app/build.gradle
@@ -88,7 +88,7 @@ android {
targetSdkVersion rootProject.ext.targetSdkVersion
compileSdk rootProject.ext.compileSdkVersion
versionCode 108
- versionName "4.0.1"
+ versionName "4.0.3"
buildConfigField("boolean", "REACT_NATIVE_UNSTABLE_USE_RUNTIME_SCHEDULER_ALWAYS", (findProperty("reactNative.unstable_useRuntimeSchedulerAlways") ?: true).toString())
}
diff --git a/apps/tlon-mobile/android/app/src/main/ic_launcher-playstore.png b/apps/tlon-mobile/android/app/src/main/ic_launcher-playstore.png
index 7404b4b8ad..6ba91a6664 100644
Binary files a/apps/tlon-mobile/android/app/src/main/ic_launcher-playstore.png and b/apps/tlon-mobile/android/app/src/main/ic_launcher-playstore.png differ
diff --git a/apps/tlon-mobile/android/app/src/main/res/drawable/ic_launcher_background.xml b/apps/tlon-mobile/android/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000000..dbfab5b176
--- /dev/null
+++ b/apps/tlon-mobile/android/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/tlon-mobile/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/apps/tlon-mobile/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
index 1a4bfc9386..c4a603d4cc 100644
--- a/apps/tlon-mobile/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
+++ b/apps/tlon-mobile/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -1,6 +1,5 @@
-
+
-
\ No newline at end of file
diff --git a/apps/tlon-mobile/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/apps/tlon-mobile/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
index 4ae7d12378..c4a603d4cc 100644
--- a/apps/tlon-mobile/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
+++ b/apps/tlon-mobile/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/apps/tlon-mobile/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/apps/tlon-mobile/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp
index 3bf1858e28..3bdb07fcfd 100644
Binary files a/apps/tlon-mobile/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp and b/apps/tlon-mobile/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/apps/tlon-mobile/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp b/apps/tlon-mobile/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp
index f7098bb639..689d863494 100644
Binary files a/apps/tlon-mobile/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp and b/apps/tlon-mobile/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp differ
diff --git a/apps/tlon-mobile/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/apps/tlon-mobile/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
index f2667dee87..6b6aba3e4a 100644
Binary files a/apps/tlon-mobile/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp and b/apps/tlon-mobile/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/apps/tlon-mobile/android/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/apps/tlon-mobile/android/app/src/main/res/mipmap-mdpi/ic_launcher.webp
index 09bdf5321b..1d65813fe7 100644
Binary files a/apps/tlon-mobile/android/app/src/main/res/mipmap-mdpi/ic_launcher.webp and b/apps/tlon-mobile/android/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/apps/tlon-mobile/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp b/apps/tlon-mobile/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp
index bbcc495eb4..28f889dfa8 100644
Binary files a/apps/tlon-mobile/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp and b/apps/tlon-mobile/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp differ
diff --git a/apps/tlon-mobile/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/apps/tlon-mobile/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
index d778996a6d..e79652444b 100644
Binary files a/apps/tlon-mobile/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp and b/apps/tlon-mobile/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/apps/tlon-mobile/android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/apps/tlon-mobile/android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
index 54c42abd5e..dd9aa9cdea 100644
Binary files a/apps/tlon-mobile/android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp and b/apps/tlon-mobile/android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/apps/tlon-mobile/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp b/apps/tlon-mobile/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp
index 77f8893a0c..aca7b0d56e 100644
Binary files a/apps/tlon-mobile/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp and b/apps/tlon-mobile/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp differ
diff --git a/apps/tlon-mobile/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/apps/tlon-mobile/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
index d860b0020b..735bb49be6 100644
Binary files a/apps/tlon-mobile/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp and b/apps/tlon-mobile/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/apps/tlon-mobile/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/apps/tlon-mobile/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
index 68045defad..cc71c7437b 100644
Binary files a/apps/tlon-mobile/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp and b/apps/tlon-mobile/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/apps/tlon-mobile/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp b/apps/tlon-mobile/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp
index a265b5ab8d..806a8ac7a6 100644
Binary files a/apps/tlon-mobile/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp and b/apps/tlon-mobile/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp differ
diff --git a/apps/tlon-mobile/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/apps/tlon-mobile/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
index 77260788a8..1e316d7ed6 100644
Binary files a/apps/tlon-mobile/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp and b/apps/tlon-mobile/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/apps/tlon-mobile/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/apps/tlon-mobile/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
index 076d9cfc2b..7f2aa9199f 100644
Binary files a/apps/tlon-mobile/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp and b/apps/tlon-mobile/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/apps/tlon-mobile/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp b/apps/tlon-mobile/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp
index fd59597c9d..193f32caf6 100644
Binary files a/apps/tlon-mobile/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp and b/apps/tlon-mobile/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp differ
diff --git a/apps/tlon-mobile/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/apps/tlon-mobile/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
index 7aa9493ace..c5467f17fc 100644
Binary files a/apps/tlon-mobile/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp and b/apps/tlon-mobile/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/apps/tlon-mobile/app.config.ts b/apps/tlon-mobile/app.config.ts
index 97f909c678..0c2b6eb1f2 100644
--- a/apps/tlon-mobile/app.config.ts
+++ b/apps/tlon-mobile/app.config.ts
@@ -30,6 +30,7 @@ export default ({ config }: ConfigContext): ExpoConfig => ({
defaultPriorityToken: process.env.DEFAULT_PRIORITY_TOKEN,
defaultTlonLoginEmail: process.env.DEFAULT_TLON_LOGIN_EMAIL,
defaultTlonLoginPassword: process.env.DEFAULT_TLON_LOGIN_PASSWORD,
+ defaultInviteLinkUrl: process.env.DEFAULT_INVITE_LINK_URL,
defaultShipLoginUrl: process.env.DEFAULT_SHIP_LOGIN_URL,
defaultShipLoginAccessCode: process.env.DEFAULT_SHIP_LOGIN_ACCESS_CODE,
recaptchaSiteKeyAndroid: process.env.RECAPTCHA_SITE_KEY_ANDROID,
@@ -37,11 +38,15 @@ export default ({ config }: ConfigContext): ExpoConfig => ({
enabledLoggers: process.env.ENABLED_LOGGERS,
ignoreCosmos: process.env.IGNORE_COSMOS,
TlonEmployeeGroup: process.env.TLON_EMPLOYEE_GROUP,
- branchKey: process.env.BRANCH_KEY,
- branchDomain: process.env.BRANCH_DOMAIN,
+ branchKey: isPreview
+ ? process.env.BRANCH_KEY_TEST
+ : process.env.BRANCH_KEY_PROD,
+ branchDomain: isPreview
+ ? process.env.BRANCH_DOMAIN_TEST
+ : process.env.BRANCH_DOMAIN_PROD,
},
ios: {
- runtimeVersion: '4.0.1',
+ runtimeVersion: '4.0.2',
// demo builds triggered by GitHub require this to be explicitly set rather than handled
// elsewhere
bundleIdentifier:
@@ -51,7 +56,7 @@ export default ({ config }: ConfigContext): ExpoConfig => ({
},
},
android: {
- runtimeVersion: '4.0.1',
+ runtimeVersion: '4.0.2',
},
plugins: [
'@react-native-firebase/app',
diff --git a/apps/tlon-mobile/assets/images/faces-dark.png b/apps/tlon-mobile/assets/images/faces-dark.png
new file mode 100644
index 0000000000..320adc43f7
Binary files /dev/null and b/apps/tlon-mobile/assets/images/faces-dark.png differ
diff --git a/apps/tlon-mobile/assets/images/faces.png b/apps/tlon-mobile/assets/images/faces.png
new file mode 100644
index 0000000000..836701efc4
Binary files /dev/null and b/apps/tlon-mobile/assets/images/faces.png differ
diff --git a/apps/tlon-mobile/assets/images/welcome-icon.png b/apps/tlon-mobile/assets/images/welcome-icon.png
new file mode 100644
index 0000000000..5ebb8479e5
Binary files /dev/null and b/apps/tlon-mobile/assets/images/welcome-icon.png differ
diff --git a/apps/tlon-mobile/cosmos.imports.ts b/apps/tlon-mobile/cosmos.imports.ts
index 5e5e00059c..41b9a78dda 100644
--- a/apps/tlon-mobile/cosmos.imports.ts
+++ b/apps/tlon-mobile/cosmos.imports.ts
@@ -8,54 +8,56 @@ import * as fixture1 from './src/fixtures/ViewReactionsSheet.fixture';
import * as fixture2 from './src/fixtures/VideoEmbed.fixture';
import * as fixture3 from './src/fixtures/UserProfileScreen.fixture';
import * as fixture4 from './src/fixtures/Text.fixture';
-import * as fixture5 from './src/fixtures/SearchBar.fixture';
-import * as fixture6 from './src/fixtures/ScreenHeader.fixture';
-import * as fixture7 from './src/fixtures/ReferenceSkeleton.fixture';
-import * as fixture8 from './src/fixtures/ProfileSheet.fixture';
-import * as fixture9 from './src/fixtures/ProfileBlock.fixture';
-import * as fixture10 from './src/fixtures/PostScreen.fixture';
-import * as fixture11 from './src/fixtures/PostReference.fixture';
-import * as fixture12 from './src/fixtures/ParentAgnosticKeyboardAvoidingView.fixture';
-import * as fixture13 from './src/fixtures/OutsideEmbed.fixture';
-import * as fixture14 from './src/fixtures/MetaEditorScreen.fixture';
-import * as fixture15 from './src/fixtures/MessageInput.fixture';
-import * as fixture16 from './src/fixtures/MessageActions.fixture';
-import * as fixture17 from './src/fixtures/InviteUsersSheet.fixture';
-import * as fixture18 from './src/fixtures/InputToolbar.fixture';
-import * as fixture19 from './src/fixtures/Input.fixture';
-import * as fixture20 from './src/fixtures/ImageViewer.fixture';
-import * as fixture21 from './src/fixtures/GroupListItem.fixture';
-import * as fixture22 from './src/fixtures/GroupList.fixture';
-import * as fixture23 from './src/fixtures/GalleryPost.fixture';
-import * as fixture24 from './src/fixtures/Form.fixture';
-import * as fixture25 from './src/fixtures/FindGroups.fixture';
-import * as fixture26 from './src/fixtures/CreateGroup.fixture';
-import * as fixture27 from './src/fixtures/ContactList.fixture';
-import * as fixture28 from './src/fixtures/ChatMessage.fixture';
-import * as fixture29 from './src/fixtures/ChannelSwitcherSheet.fixture';
-import * as fixture30 from './src/fixtures/ChannelHeader.fixture';
-import * as fixture31 from './src/fixtures/ChannelDivider.fixture';
-import * as fixture32 from './src/fixtures/Channel.fixture';
-import * as fixture33 from './src/fixtures/Button.fixture';
-import * as fixture34 from './src/fixtures/BlockSectionList.fixture';
-import * as fixture35 from './src/fixtures/Avatar.fixture';
-import * as fixture36 from './src/fixtures/AudioEmbed.fixture';
-import * as fixture37 from './src/fixtures/AttachmentPreviewList.fixture';
-import * as fixture38 from './src/fixtures/AddGroupSheet.fixture';
-import * as fixture39 from './src/fixtures/Activity.fixture';
-import * as fixture40 from './src/fixtures/DetailView/NotebookDetailView.fixture';
-import * as fixture41 from './src/fixtures/DetailView/GalleryDetailView.fixture';
-import * as fixture42 from './src/fixtures/DetailView/ChatDetailView.fixture';
-import * as fixture43 from './src/fixtures/ActionSheet/SendPostRetrySheet.fixture';
-import * as fixture44 from './src/fixtures/ActionSheet/ProfileSheet.fixture';
-import * as fixture45 from './src/fixtures/ActionSheet/GroupPreviewSheet.fixture';
-import * as fixture46 from './src/fixtures/ActionSheet/GroupJoinRequestSheet.fixture';
-import * as fixture47 from './src/fixtures/ActionSheet/GenericActionSheet.fixture';
-import * as fixture48 from './src/fixtures/ActionSheet/EditSectionNameSheet.fixture';
-import * as fixture49 from './src/fixtures/ActionSheet/DeleteSheet.fixture';
-import * as fixture50 from './src/fixtures/ActionSheet/CreateChannelSheet.fixture';
-import * as fixture51 from './src/fixtures/ActionSheet/AttachmentSheet.fixture';
-import * as fixture52 from './src/fixtures/ActionSheet/AddGalleryPostSheet.fixture';
+import * as fixture5 from './src/fixtures/SetNicknameScreen.fixture';
+import * as fixture6 from './src/fixtures/SearchBar.fixture';
+import * as fixture7 from './src/fixtures/ScreenHeader.fixture';
+import * as fixture8 from './src/fixtures/ReferenceSkeleton.fixture';
+import * as fixture9 from './src/fixtures/ProfileSheet.fixture';
+import * as fixture10 from './src/fixtures/ProfileBlock.fixture';
+import * as fixture11 from './src/fixtures/PostScreen.fixture';
+import * as fixture12 from './src/fixtures/PostReference.fixture';
+import * as fixture13 from './src/fixtures/ParentAgnosticKeyboardAvoidingView.fixture';
+import * as fixture14 from './src/fixtures/OutsideEmbed.fixture';
+import * as fixture15 from './src/fixtures/Onboarding.fixture';
+import * as fixture16 from './src/fixtures/MetaEditorScreen.fixture';
+import * as fixture17 from './src/fixtures/MessageInput.fixture';
+import * as fixture18 from './src/fixtures/MessageActions.fixture';
+import * as fixture19 from './src/fixtures/InviteUsersSheet.fixture';
+import * as fixture20 from './src/fixtures/InputToolbar.fixture';
+import * as fixture21 from './src/fixtures/Input.fixture';
+import * as fixture22 from './src/fixtures/ImageViewer.fixture';
+import * as fixture23 from './src/fixtures/GroupListItem.fixture';
+import * as fixture24 from './src/fixtures/GroupList.fixture';
+import * as fixture25 from './src/fixtures/GalleryPost.fixture';
+import * as fixture26 from './src/fixtures/Form.fixture';
+import * as fixture27 from './src/fixtures/FindGroups.fixture';
+import * as fixture28 from './src/fixtures/CreateGroup.fixture';
+import * as fixture29 from './src/fixtures/ContactList.fixture';
+import * as fixture30 from './src/fixtures/ChatMessage.fixture';
+import * as fixture31 from './src/fixtures/ChannelSwitcherSheet.fixture';
+import * as fixture32 from './src/fixtures/ChannelHeader.fixture';
+import * as fixture33 from './src/fixtures/ChannelDivider.fixture';
+import * as fixture34 from './src/fixtures/Channel.fixture';
+import * as fixture35 from './src/fixtures/Button.fixture';
+import * as fixture36 from './src/fixtures/BlockSectionList.fixture';
+import * as fixture37 from './src/fixtures/Avatar.fixture';
+import * as fixture38 from './src/fixtures/AudioEmbed.fixture';
+import * as fixture39 from './src/fixtures/AttachmentPreviewList.fixture';
+import * as fixture40 from './src/fixtures/AddGroupSheet.fixture';
+import * as fixture41 from './src/fixtures/Activity.fixture';
+import * as fixture42 from './src/fixtures/DetailView/NotebookDetailView.fixture';
+import * as fixture43 from './src/fixtures/DetailView/GalleryDetailView.fixture';
+import * as fixture44 from './src/fixtures/DetailView/ChatDetailView.fixture';
+import * as fixture45 from './src/fixtures/ActionSheet/SendPostRetrySheet.fixture';
+import * as fixture46 from './src/fixtures/ActionSheet/ProfileSheet.fixture';
+import * as fixture47 from './src/fixtures/ActionSheet/GroupPreviewSheet.fixture';
+import * as fixture48 from './src/fixtures/ActionSheet/GroupJoinRequestSheet.fixture';
+import * as fixture49 from './src/fixtures/ActionSheet/GenericActionSheet.fixture';
+import * as fixture50 from './src/fixtures/ActionSheet/EditSectionNameSheet.fixture';
+import * as fixture51 from './src/fixtures/ActionSheet/DeleteSheet.fixture';
+import * as fixture52 from './src/fixtures/ActionSheet/CreateChannelSheet.fixture';
+import * as fixture53 from './src/fixtures/ActionSheet/AttachmentSheet.fixture';
+import * as fixture54 from './src/fixtures/ActionSheet/AddGalleryPostSheet.fixture';
import * as decorator0 from './src/fixtures/cosmos.decorator';
@@ -70,54 +72,56 @@ const fixtures = {
'src/fixtures/VideoEmbed.fixture.tsx': { module: fixture2 },
'src/fixtures/UserProfileScreen.fixture.tsx': { module: fixture3 },
'src/fixtures/Text.fixture.tsx': { module: fixture4 },
- 'src/fixtures/SearchBar.fixture.tsx': { module: fixture5 },
- 'src/fixtures/ScreenHeader.fixture.tsx': { module: fixture6 },
- 'src/fixtures/ReferenceSkeleton.fixture.tsx': { module: fixture7 },
- 'src/fixtures/ProfileSheet.fixture.tsx': { module: fixture8 },
- 'src/fixtures/ProfileBlock.fixture.tsx': { module: fixture9 },
- 'src/fixtures/PostScreen.fixture.tsx': { module: fixture10 },
- 'src/fixtures/PostReference.fixture.tsx': { module: fixture11 },
- 'src/fixtures/ParentAgnosticKeyboardAvoidingView.fixture.tsx': { module: fixture12 },
- 'src/fixtures/OutsideEmbed.fixture.tsx': { module: fixture13 },
- 'src/fixtures/MetaEditorScreen.fixture.tsx': { module: fixture14 },
- 'src/fixtures/MessageInput.fixture.tsx': { module: fixture15 },
- 'src/fixtures/MessageActions.fixture.tsx': { module: fixture16 },
- 'src/fixtures/InviteUsersSheet.fixture.tsx': { module: fixture17 },
- 'src/fixtures/InputToolbar.fixture.tsx': { module: fixture18 },
- 'src/fixtures/Input.fixture.tsx': { module: fixture19 },
- 'src/fixtures/ImageViewer.fixture.tsx': { module: fixture20 },
- 'src/fixtures/GroupListItem.fixture.tsx': { module: fixture21 },
- 'src/fixtures/GroupList.fixture.tsx': { module: fixture22 },
- 'src/fixtures/GalleryPost.fixture.tsx': { module: fixture23 },
- 'src/fixtures/Form.fixture.tsx': { module: fixture24 },
- 'src/fixtures/FindGroups.fixture.tsx': { module: fixture25 },
- 'src/fixtures/CreateGroup.fixture.tsx': { module: fixture26 },
- 'src/fixtures/ContactList.fixture.tsx': { module: fixture27 },
- 'src/fixtures/ChatMessage.fixture.tsx': { module: fixture28 },
- 'src/fixtures/ChannelSwitcherSheet.fixture.tsx': { module: fixture29 },
- 'src/fixtures/ChannelHeader.fixture.tsx': { module: fixture30 },
- 'src/fixtures/ChannelDivider.fixture.tsx': { module: fixture31 },
- 'src/fixtures/Channel.fixture.tsx': { module: fixture32 },
- 'src/fixtures/Button.fixture.tsx': { module: fixture33 },
- 'src/fixtures/BlockSectionList.fixture.tsx': { module: fixture34 },
- 'src/fixtures/Avatar.fixture.tsx': { module: fixture35 },
- 'src/fixtures/AudioEmbed.fixture.tsx': { module: fixture36 },
- 'src/fixtures/AttachmentPreviewList.fixture.tsx': { module: fixture37 },
- 'src/fixtures/AddGroupSheet.fixture.tsx': { module: fixture38 },
- 'src/fixtures/Activity.fixture.tsx': { module: fixture39 },
- 'src/fixtures/DetailView/NotebookDetailView.fixture.tsx': { module: fixture40 },
- 'src/fixtures/DetailView/GalleryDetailView.fixture.tsx': { module: fixture41 },
- 'src/fixtures/DetailView/ChatDetailView.fixture.tsx': { module: fixture42 },
- 'src/fixtures/ActionSheet/SendPostRetrySheet.fixture.tsx': { module: fixture43 },
- 'src/fixtures/ActionSheet/ProfileSheet.fixture.tsx': { module: fixture44 },
- 'src/fixtures/ActionSheet/GroupPreviewSheet.fixture.tsx': { module: fixture45 },
- 'src/fixtures/ActionSheet/GroupJoinRequestSheet.fixture.tsx': { module: fixture46 },
- 'src/fixtures/ActionSheet/GenericActionSheet.fixture.tsx': { module: fixture47 },
- 'src/fixtures/ActionSheet/EditSectionNameSheet.fixture.tsx': { module: fixture48 },
- 'src/fixtures/ActionSheet/DeleteSheet.fixture.tsx': { module: fixture49 },
- 'src/fixtures/ActionSheet/CreateChannelSheet.fixture.tsx': { module: fixture50 },
- 'src/fixtures/ActionSheet/AttachmentSheet.fixture.tsx': { module: fixture51 },
- 'src/fixtures/ActionSheet/AddGalleryPostSheet.fixture.tsx': { module: fixture52 }
+ 'src/fixtures/SetNicknameScreen.fixture.tsx': { module: fixture5 },
+ 'src/fixtures/SearchBar.fixture.tsx': { module: fixture6 },
+ 'src/fixtures/ScreenHeader.fixture.tsx': { module: fixture7 },
+ 'src/fixtures/ReferenceSkeleton.fixture.tsx': { module: fixture8 },
+ 'src/fixtures/ProfileSheet.fixture.tsx': { module: fixture9 },
+ 'src/fixtures/ProfileBlock.fixture.tsx': { module: fixture10 },
+ 'src/fixtures/PostScreen.fixture.tsx': { module: fixture11 },
+ 'src/fixtures/PostReference.fixture.tsx': { module: fixture12 },
+ 'src/fixtures/ParentAgnosticKeyboardAvoidingView.fixture.tsx': { module: fixture13 },
+ 'src/fixtures/OutsideEmbed.fixture.tsx': { module: fixture14 },
+ 'src/fixtures/Onboarding.fixture.tsx': { module: fixture15 },
+ 'src/fixtures/MetaEditorScreen.fixture.tsx': { module: fixture16 },
+ 'src/fixtures/MessageInput.fixture.tsx': { module: fixture17 },
+ 'src/fixtures/MessageActions.fixture.tsx': { module: fixture18 },
+ 'src/fixtures/InviteUsersSheet.fixture.tsx': { module: fixture19 },
+ 'src/fixtures/InputToolbar.fixture.tsx': { module: fixture20 },
+ 'src/fixtures/Input.fixture.tsx': { module: fixture21 },
+ 'src/fixtures/ImageViewer.fixture.tsx': { module: fixture22 },
+ 'src/fixtures/GroupListItem.fixture.tsx': { module: fixture23 },
+ 'src/fixtures/GroupList.fixture.tsx': { module: fixture24 },
+ 'src/fixtures/GalleryPost.fixture.tsx': { module: fixture25 },
+ 'src/fixtures/Form.fixture.tsx': { module: fixture26 },
+ 'src/fixtures/FindGroups.fixture.tsx': { module: fixture27 },
+ 'src/fixtures/CreateGroup.fixture.tsx': { module: fixture28 },
+ 'src/fixtures/ContactList.fixture.tsx': { module: fixture29 },
+ 'src/fixtures/ChatMessage.fixture.tsx': { module: fixture30 },
+ 'src/fixtures/ChannelSwitcherSheet.fixture.tsx': { module: fixture31 },
+ 'src/fixtures/ChannelHeader.fixture.tsx': { module: fixture32 },
+ 'src/fixtures/ChannelDivider.fixture.tsx': { module: fixture33 },
+ 'src/fixtures/Channel.fixture.tsx': { module: fixture34 },
+ 'src/fixtures/Button.fixture.tsx': { module: fixture35 },
+ 'src/fixtures/BlockSectionList.fixture.tsx': { module: fixture36 },
+ 'src/fixtures/Avatar.fixture.tsx': { module: fixture37 },
+ 'src/fixtures/AudioEmbed.fixture.tsx': { module: fixture38 },
+ 'src/fixtures/AttachmentPreviewList.fixture.tsx': { module: fixture39 },
+ 'src/fixtures/AddGroupSheet.fixture.tsx': { module: fixture40 },
+ 'src/fixtures/Activity.fixture.tsx': { module: fixture41 },
+ 'src/fixtures/DetailView/NotebookDetailView.fixture.tsx': { module: fixture42 },
+ 'src/fixtures/DetailView/GalleryDetailView.fixture.tsx': { module: fixture43 },
+ 'src/fixtures/DetailView/ChatDetailView.fixture.tsx': { module: fixture44 },
+ 'src/fixtures/ActionSheet/SendPostRetrySheet.fixture.tsx': { module: fixture45 },
+ 'src/fixtures/ActionSheet/ProfileSheet.fixture.tsx': { module: fixture46 },
+ 'src/fixtures/ActionSheet/GroupPreviewSheet.fixture.tsx': { module: fixture47 },
+ 'src/fixtures/ActionSheet/GroupJoinRequestSheet.fixture.tsx': { module: fixture48 },
+ 'src/fixtures/ActionSheet/GenericActionSheet.fixture.tsx': { module: fixture49 },
+ 'src/fixtures/ActionSheet/EditSectionNameSheet.fixture.tsx': { module: fixture50 },
+ 'src/fixtures/ActionSheet/DeleteSheet.fixture.tsx': { module: fixture51 },
+ 'src/fixtures/ActionSheet/CreateChannelSheet.fixture.tsx': { module: fixture52 },
+ 'src/fixtures/ActionSheet/AttachmentSheet.fixture.tsx': { module: fixture53 },
+ 'src/fixtures/ActionSheet/AddGalleryPostSheet.fixture.tsx': { module: fixture54 }
};
const decorators = {
diff --git a/apps/tlon-mobile/ios/Landscape.xcodeproj/project.pbxproj b/apps/tlon-mobile/ios/Landscape.xcodeproj/project.pbxproj
index 0758dac6f3..76206dad3c 100644
--- a/apps/tlon-mobile/ios/Landscape.xcodeproj/project.pbxproj
+++ b/apps/tlon-mobile/ios/Landscape.xcodeproj/project.pbxproj
@@ -1395,7 +1395,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
- MARKETING_VERSION = 4.0.1;
+ MARKETING_VERSION = 4.0.3;
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
@@ -1433,7 +1433,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
- MARKETING_VERSION = 4.0.1;
+ MARKETING_VERSION = 4.0.3;
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
@@ -1657,7 +1657,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
- MARKETING_VERSION = 4.0.1;
+ MARKETING_VERSION = 4.0.2;
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
@@ -1700,7 +1700,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
- MARKETING_VERSION = 4.0.1;
+ MARKETING_VERSION = 4.0.2;
OTHER_LDFLAGS = (
"$(inherited)",
"-ObjC",
diff --git a/apps/tlon-mobile/ios/Landscape/Images-preview.xcassets/AppIcon.appiconset/120.png b/apps/tlon-mobile/ios/Landscape/Images-preview.xcassets/AppIcon.appiconset/120.png
deleted file mode 100644
index c7e4c08980..0000000000
Binary files a/apps/tlon-mobile/ios/Landscape/Images-preview.xcassets/AppIcon.appiconset/120.png and /dev/null differ
diff --git a/apps/tlon-mobile/ios/Landscape/Images-preview.xcassets/AppIcon.appiconset/180.png b/apps/tlon-mobile/ios/Landscape/Images-preview.xcassets/AppIcon.appiconset/180.png
deleted file mode 100644
index 54b81b6271..0000000000
Binary files a/apps/tlon-mobile/ios/Landscape/Images-preview.xcassets/AppIcon.appiconset/180.png and /dev/null differ
diff --git a/apps/tlon-mobile/ios/Landscape/Images-preview.xcassets/AppIcon.appiconset/40.png b/apps/tlon-mobile/ios/Landscape/Images-preview.xcassets/AppIcon.appiconset/40.png
deleted file mode 100644
index 53e167140b..0000000000
Binary files a/apps/tlon-mobile/ios/Landscape/Images-preview.xcassets/AppIcon.appiconset/40.png and /dev/null differ
diff --git a/apps/tlon-mobile/ios/Landscape/Images-preview.xcassets/AppIcon.appiconset/58.png b/apps/tlon-mobile/ios/Landscape/Images-preview.xcassets/AppIcon.appiconset/58.png
deleted file mode 100644
index ea12cb15fe..0000000000
Binary files a/apps/tlon-mobile/ios/Landscape/Images-preview.xcassets/AppIcon.appiconset/58.png and /dev/null differ
diff --git a/apps/tlon-mobile/ios/Landscape/Images-preview.xcassets/AppIcon.appiconset/60.png b/apps/tlon-mobile/ios/Landscape/Images-preview.xcassets/AppIcon.appiconset/60.png
deleted file mode 100644
index 5421dbb358..0000000000
Binary files a/apps/tlon-mobile/ios/Landscape/Images-preview.xcassets/AppIcon.appiconset/60.png and /dev/null differ
diff --git a/apps/tlon-mobile/ios/Landscape/Images-preview.xcassets/AppIcon.appiconset/80.png b/apps/tlon-mobile/ios/Landscape/Images-preview.xcassets/AppIcon.appiconset/80.png
deleted file mode 100644
index 195d2a2656..0000000000
Binary files a/apps/tlon-mobile/ios/Landscape/Images-preview.xcassets/AppIcon.appiconset/80.png and /dev/null differ
diff --git a/apps/tlon-mobile/ios/Landscape/Images-preview.xcassets/AppIcon.appiconset/87.png b/apps/tlon-mobile/ios/Landscape/Images-preview.xcassets/AppIcon.appiconset/87.png
deleted file mode 100644
index 148cecadd5..0000000000
Binary files a/apps/tlon-mobile/ios/Landscape/Images-preview.xcassets/AppIcon.appiconset/87.png and /dev/null differ
diff --git a/apps/tlon-mobile/ios/Landscape/Images-preview.xcassets/AppIcon.appiconset/Contents.json b/apps/tlon-mobile/ios/Landscape/Images-preview.xcassets/AppIcon.appiconset/Contents.json
index d8507e5d58..b3f44eb295 100644
--- a/apps/tlon-mobile/ios/Landscape/Images-preview.xcassets/AppIcon.appiconset/Contents.json
+++ b/apps/tlon-mobile/ios/Landscape/Images-preview.xcassets/AppIcon.appiconset/Contents.json
@@ -1,57 +1,9 @@
{
"images" : [
{
- "filename" : "40.png",
- "idiom" : "iphone",
- "scale" : "2x",
- "size" : "20x20"
- },
- {
- "filename" : "60.png",
- "idiom" : "iphone",
- "scale" : "3x",
- "size" : "20x20"
- },
- {
- "filename" : "58.png",
- "idiom" : "iphone",
- "scale" : "2x",
- "size" : "29x29"
- },
- {
- "filename" : "87.png",
- "idiom" : "iphone",
- "scale" : "3x",
- "size" : "29x29"
- },
- {
- "filename" : "80.png",
- "idiom" : "iphone",
- "scale" : "2x",
- "size" : "40x40"
- },
- {
- "filename" : "120.png",
- "idiom" : "iphone",
- "scale" : "3x",
- "size" : "40x40"
- },
- {
- "filename" : "120.png",
- "idiom" : "iphone",
- "scale" : "2x",
- "size" : "60x60"
- },
- {
- "filename" : "180.png",
- "idiom" : "iphone",
- "scale" : "3x",
- "size" : "60x60"
- },
- {
- "filename" : "Icon-App-iTunes.png",
- "idiom" : "ios-marketing",
- "scale" : "1x",
+ "filename" : "Icon.png",
+ "idiom" : "universal",
+ "platform" : "ios",
"size" : "1024x1024"
}
],
diff --git a/apps/tlon-mobile/ios/Landscape/Images-preview.xcassets/AppIcon.appiconset/Icon-App-iTunes.png b/apps/tlon-mobile/ios/Landscape/Images-preview.xcassets/AppIcon.appiconset/Icon-App-iTunes.png
deleted file mode 100644
index f249c3e686..0000000000
Binary files a/apps/tlon-mobile/ios/Landscape/Images-preview.xcassets/AppIcon.appiconset/Icon-App-iTunes.png and /dev/null differ
diff --git a/apps/tlon-mobile/ios/Landscape/Images-preview.xcassets/AppIcon.appiconset/Icon.png b/apps/tlon-mobile/ios/Landscape/Images-preview.xcassets/AppIcon.appiconset/Icon.png
new file mode 100644
index 0000000000..2773759206
Binary files /dev/null and b/apps/tlon-mobile/ios/Landscape/Images-preview.xcassets/AppIcon.appiconset/Icon.png differ
diff --git a/apps/tlon-mobile/ios/Landscape/Images.xcassets/AppIcon.appiconset/Contents.json b/apps/tlon-mobile/ios/Landscape/Images.xcassets/AppIcon.appiconset/Contents.json
index 3c16f0a0fe..b3f44eb295 100644
--- a/apps/tlon-mobile/ios/Landscape/Images.xcassets/AppIcon.appiconset/Contents.json
+++ b/apps/tlon-mobile/ios/Landscape/Images.xcassets/AppIcon.appiconset/Contents.json
@@ -1,57 +1,9 @@
{
"images" : [
{
- "filename" : "Icon_40x40.png",
- "idiom" : "iphone",
- "scale" : "2x",
- "size" : "20x20"
- },
- {
- "filename" : "Icon_60×60.png",
- "idiom" : "iphone",
- "scale" : "3x",
- "size" : "20x20"
- },
- {
- "filename" : "Icon_58x58.png",
- "idiom" : "iphone",
- "scale" : "2x",
- "size" : "29x29"
- },
- {
- "filename" : "Icon_87×87.png",
- "idiom" : "iphone",
- "scale" : "3x",
- "size" : "29x29"
- },
- {
- "filename" : "Icon_80x80.png",
- "idiom" : "iphone",
- "scale" : "2x",
- "size" : "40x40"
- },
- {
- "filename" : "Icon_120×120.png",
- "idiom" : "iphone",
- "scale" : "3x",
- "size" : "40x40"
- },
- {
- "filename" : "Icon_120x120.png",
- "idiom" : "iphone",
- "scale" : "2x",
- "size" : "60x60"
- },
- {
- "filename" : "Icon_180×180.png",
- "idiom" : "iphone",
- "scale" : "3x",
- "size" : "60x60"
- },
- {
- "filename" : "Icon-App-iTunes.png",
- "idiom" : "ios-marketing",
- "scale" : "1x",
+ "filename" : "Icon.png",
+ "idiom" : "universal",
+ "platform" : "ios",
"size" : "1024x1024"
}
],
diff --git a/apps/tlon-mobile/ios/Landscape/Images.xcassets/AppIcon.appiconset/Icon-App-iTunes.png b/apps/tlon-mobile/ios/Landscape/Images.xcassets/AppIcon.appiconset/Icon-App-iTunes.png
deleted file mode 100644
index cd17434023..0000000000
Binary files a/apps/tlon-mobile/ios/Landscape/Images.xcassets/AppIcon.appiconset/Icon-App-iTunes.png and /dev/null differ
diff --git a/apps/tlon-mobile/ios/Landscape/Images.xcassets/AppIcon.appiconset/Icon.png b/apps/tlon-mobile/ios/Landscape/Images.xcassets/AppIcon.appiconset/Icon.png
new file mode 100644
index 0000000000..0d7bf11ebf
Binary files /dev/null and b/apps/tlon-mobile/ios/Landscape/Images.xcassets/AppIcon.appiconset/Icon.png differ
diff --git a/apps/tlon-mobile/ios/Landscape/Images.xcassets/AppIcon.appiconset/Icon_120x120.png b/apps/tlon-mobile/ios/Landscape/Images.xcassets/AppIcon.appiconset/Icon_120x120.png
deleted file mode 100644
index 1eafe686b9..0000000000
Binary files a/apps/tlon-mobile/ios/Landscape/Images.xcassets/AppIcon.appiconset/Icon_120x120.png and /dev/null differ
diff --git "a/apps/tlon-mobile/ios/Landscape/Images.xcassets/AppIcon.appiconset/Icon_120\303\227120.png" "b/apps/tlon-mobile/ios/Landscape/Images.xcassets/AppIcon.appiconset/Icon_120\303\227120.png"
deleted file mode 100644
index 158729d6c9..0000000000
Binary files "a/apps/tlon-mobile/ios/Landscape/Images.xcassets/AppIcon.appiconset/Icon_120\303\227120.png" and /dev/null differ
diff --git "a/apps/tlon-mobile/ios/Landscape/Images.xcassets/AppIcon.appiconset/Icon_180\303\227180.png" "b/apps/tlon-mobile/ios/Landscape/Images.xcassets/AppIcon.appiconset/Icon_180\303\227180.png"
deleted file mode 100644
index 8d3788407c..0000000000
Binary files "a/apps/tlon-mobile/ios/Landscape/Images.xcassets/AppIcon.appiconset/Icon_180\303\227180.png" and /dev/null differ
diff --git a/apps/tlon-mobile/ios/Landscape/Images.xcassets/AppIcon.appiconset/Icon_40x40.png b/apps/tlon-mobile/ios/Landscape/Images.xcassets/AppIcon.appiconset/Icon_40x40.png
deleted file mode 100644
index 25c6f30d16..0000000000
Binary files a/apps/tlon-mobile/ios/Landscape/Images.xcassets/AppIcon.appiconset/Icon_40x40.png and /dev/null differ
diff --git a/apps/tlon-mobile/ios/Landscape/Images.xcassets/AppIcon.appiconset/Icon_58x58.png b/apps/tlon-mobile/ios/Landscape/Images.xcassets/AppIcon.appiconset/Icon_58x58.png
deleted file mode 100644
index 6f00a485eb..0000000000
Binary files a/apps/tlon-mobile/ios/Landscape/Images.xcassets/AppIcon.appiconset/Icon_58x58.png and /dev/null differ
diff --git "a/apps/tlon-mobile/ios/Landscape/Images.xcassets/AppIcon.appiconset/Icon_60\303\22760.png" "b/apps/tlon-mobile/ios/Landscape/Images.xcassets/AppIcon.appiconset/Icon_60\303\22760.png"
deleted file mode 100644
index 7222e650e5..0000000000
Binary files "a/apps/tlon-mobile/ios/Landscape/Images.xcassets/AppIcon.appiconset/Icon_60\303\22760.png" and /dev/null differ
diff --git a/apps/tlon-mobile/ios/Landscape/Images.xcassets/AppIcon.appiconset/Icon_80x80.png b/apps/tlon-mobile/ios/Landscape/Images.xcassets/AppIcon.appiconset/Icon_80x80.png
deleted file mode 100644
index 3a2d27fb41..0000000000
Binary files a/apps/tlon-mobile/ios/Landscape/Images.xcassets/AppIcon.appiconset/Icon_80x80.png and /dev/null differ
diff --git "a/apps/tlon-mobile/ios/Landscape/Images.xcassets/AppIcon.appiconset/Icon_87\303\22787.png" "b/apps/tlon-mobile/ios/Landscape/Images.xcassets/AppIcon.appiconset/Icon_87\303\22787.png"
deleted file mode 100644
index f7d3f647f5..0000000000
Binary files "a/apps/tlon-mobile/ios/Landscape/Images.xcassets/AppIcon.appiconset/Icon_87\303\22787.png" and /dev/null differ
diff --git a/apps/tlon-mobile/src/App.main.tsx b/apps/tlon-mobile/src/App.main.tsx
index 25cca6511c..a8fe41e7ae 100644
--- a/apps/tlon-mobile/src/App.main.tsx
+++ b/apps/tlon-mobile/src/App.main.tsx
@@ -9,20 +9,23 @@ import {
NavigationContainerRefWithCurrent,
useNavigationContainerRef,
} from '@react-navigation/native';
-import { createNativeStackNavigator } from '@react-navigation/native-stack';
import ErrorBoundary from '@tloncorp/app/ErrorBoundary';
import { BranchProvider, useBranch } from '@tloncorp/app/contexts/branch';
import { ShipProvider, useShip } from '@tloncorp/app/contexts/ship';
import { SignupProvider } from '@tloncorp/app/contexts/signup';
import { useIsDarkMode } from '@tloncorp/app/hooks/useIsDarkMode';
-import { useScreenOptions } from '@tloncorp/app/hooks/useScreenOptions';
import { useMigrations } from '@tloncorp/app/lib/nativeDb';
import { Provider as TamaguiProvider } from '@tloncorp/app/provider';
import { FeatureFlagConnectedInstrumentationProvider } from '@tloncorp/app/utils/perf';
import { posthogAsync } from '@tloncorp/app/utils/posthog';
import { QueryClientProvider, queryClient } from '@tloncorp/shared/dist/api';
-import { LoadingSpinner, PortalProvider, Text, View } from '@tloncorp/ui';
-import { usePreloadedEmojis } from '@tloncorp/ui';
+import {
+ LoadingSpinner,
+ PortalProvider,
+ Text,
+ View,
+ usePreloadedEmojis,
+} from '@tloncorp/ui';
import { PostHogProvider } from 'posthog-react-native';
import type { PropsWithChildren } from 'react';
import { useEffect, useState } from 'react';
@@ -30,31 +33,14 @@ import { StatusBar } from 'react-native';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { SafeAreaProvider } from 'react-native-safe-area-context';
+import { OnboardingStack } from './OnboardingStack';
import AuthenticatedApp from './components/AuthenticatedApp';
-import { CheckVerifyScreen } from './screens/Onboarding/CheckVerifyScreen';
-import { EULAScreen } from './screens/Onboarding/EULAScreen';
-import { InventoryCheckScreen } from './screens/Onboarding/InventoryCheckScreen';
-import { InviteLinkScreen } from './screens/Onboarding/InviteLinkScreen';
-import { JoinWaitListScreen } from './screens/Onboarding/JoinWaitListScreen';
-import { RequestPhoneVerifyScreen } from './screens/Onboarding/RequestPhoneVerifyScreen';
-import { ReserveShipScreen } from './screens/Onboarding/ReserveShipScreen';
-import { ResetPasswordScreen } from './screens/Onboarding/ResetPasswordScreen';
-import { SetNicknameScreen } from './screens/Onboarding/SetNicknameScreen';
-import { SetTelemetryScreen } from './screens/Onboarding/SetTelemetryScreen';
-import { ShipLoginScreen } from './screens/Onboarding/ShipLoginScreen';
-import { SignUpEmailScreen } from './screens/Onboarding/SignUpEmailScreen';
-import { SignUpPasswordScreen } from './screens/Onboarding/SignUpPasswordScreen';
-import { TlonLoginScreen } from './screens/Onboarding/TlonLoginScreen';
-import { WelcomeScreen } from './screens/Onboarding/WelcomeScreen';
-import type { OnboardingStackParamList } from './types';
type Props = {
wer?: string;
channelId?: string;
};
-const OnboardingStack = createNativeStackNavigator();
-
// Android notification tap handler passes initial params here
const App = ({
wer: notificationPath,
@@ -65,12 +51,6 @@ const App = ({
const { isLoading, isAuthenticated } = useShip();
const [connected, setConnected] = useState(true);
const { lure, priorityToken } = useBranch();
- const screenOptions = useScreenOptions();
-
- const onboardingScreenOptions = {
- ...screenOptions,
- headerShown: false,
- };
usePreloadedEmojis();
@@ -101,66 +81,7 @@ const App = ({
}}
/>
) : (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
)
) : (
();
+
+export function OnboardingStack() {
+ const screenOptions = useScreenOptions();
+
+ const onboardingScreenOptions = {
+ ...screenOptions,
+ headerShown: false,
+ };
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/apps/tlon-mobile/src/components/AuthenticatedApp.tsx b/apps/tlon-mobile/src/components/AuthenticatedApp.tsx
index 939b6a9b91..a31c3b2746 100644
--- a/apps/tlon-mobile/src/components/AuthenticatedApp.tsx
+++ b/apps/tlon-mobile/src/components/AuthenticatedApp.tsx
@@ -42,7 +42,6 @@ function AuthenticatedApp({
shipName: ship ?? '',
shipUrl: shipUrl ?? '',
onReset: () => sync.syncStart(),
- verbose: __DEV__,
onChannelReset: () => sync.handleDiscontinuity(),
onChannelStatusChange: sync.handleChannelStatusChange,
});
diff --git a/apps/tlon-mobile/src/fixtures/DetailView/detailViewFixtureBase.tsx b/apps/tlon-mobile/src/fixtures/DetailView/detailViewFixtureBase.tsx
index 408a7a4bc1..f0deeb7638 100644
--- a/apps/tlon-mobile/src/fixtures/DetailView/detailViewFixtureBase.tsx
+++ b/apps/tlon-mobile/src/fixtures/DetailView/detailViewFixtureBase.tsx
@@ -39,6 +39,7 @@ export const DetailViewFixture = ({
channel,
}}
posts={replies}
+ isLoadingPosts={false}
channel={channel}
sendReply={async () => {}}
onPressRetry={() => {}}
diff --git a/apps/tlon-mobile/src/fixtures/Onboarding.fixture.tsx b/apps/tlon-mobile/src/fixtures/Onboarding.fixture.tsx
new file mode 100644
index 0000000000..02922c502f
--- /dev/null
+++ b/apps/tlon-mobile/src/fixtures/Onboarding.fixture.tsx
@@ -0,0 +1,236 @@
+import { NavigationContainer } from '@react-navigation/native';
+import {
+ Context as BranchContext,
+ LureData,
+} from '@tloncorp/app/contexts/branch';
+import {
+ DeepLinkData,
+ QueryClientProvider,
+ queryClient,
+} from '@tloncorp/shared/dist';
+import { PropsWithChildren, useState } from 'react';
+
+import { OnboardingStack, OnboardingStackNavigator } from '../OnboardingStack';
+import { OnboardingProvider } from '../lib/OnboardingContext';
+import { CheckVerifyScreen } from '../screens/Onboarding/CheckVerifyScreen';
+import { EULAScreen } from '../screens/Onboarding/EULAScreen';
+import { InventoryCheckScreen } from '../screens/Onboarding/InventoryCheckScreen';
+import { JoinWaitListScreen } from '../screens/Onboarding/JoinWaitListScreen';
+import { PasteInviteLinkScreen } from '../screens/Onboarding/PasteInviteLinkScreen';
+import { RequestPhoneVerifyScreen } from '../screens/Onboarding/RequestPhoneVerifyScreen';
+import { ReserveShipScreen } from '../screens/Onboarding/ReserveShipScreen';
+import { SetNicknameScreen } from '../screens/Onboarding/SetNicknameScreen';
+import { SetTelemetryScreen } from '../screens/Onboarding/SetTelemetryScreen';
+import { ShipLoginScreen } from '../screens/Onboarding/ShipLoginScreen';
+import { SignUpEmailScreen } from '../screens/Onboarding/SignUpEmailScreen';
+import { SignUpPasswordScreen } from '../screens/Onboarding/SignUpPasswordScreen';
+import { TlonLoginScreen } from '../screens/Onboarding/TlonLoginScreen';
+import { WelcomeScreen } from '../screens/Onboarding/WelcomeScreen';
+import { OnboardingStackParamList, User } from '../types';
+import { exampleContacts } from './contentHelpers';
+import { group } from './fakeData';
+
+const sampleUser = {
+ id: '1',
+ nickname: 'test',
+ email: 'dan@tlon.io',
+ ships: [],
+ admin: false,
+ verified: false,
+ requirePhoneNumberVerification: false,
+};
+
+function OnboardingFixture({
+ hasGroupInvite,
+ children,
+}: PropsWithChildren<{ hasGroupInvite: boolean }>) {
+ const [lure, setLure] = useState(
+ hasGroupInvite
+ ? {
+ id: group.id,
+ shouldAutoJoin: true,
+ inviterUserId: exampleContacts.ed.id,
+ inviterNickname: exampleContacts.ed.nickname,
+ invitedGroupId: group.id,
+ invitedGroupTitle: group.title ?? undefined,
+ invitedGroupDescription: group.description ?? undefined,
+ invitedGroupIconImageUrl: group.iconImage ?? undefined,
+ invitedGroupiconImageColor: group.iconImageColor ?? undefined,
+ }
+ : undefined
+ );
+ return (
+
+ Promise.resolve('abc'),
+ execRecaptchaLogin: () => Promise.resolve('abc'),
+ getLandscapeAuthCookie: () => Promise.resolve('abc'),
+ //@ts-expect-error partial implementation
+ hostingApi: {
+ signUpHostingUser: async () => Promise.resolve({}),
+ logInHostingUser: () => Promise.resolve(sampleUser),
+ getHostingAvailability: async () =>
+ Promise.resolve({ enabled: true, validEmail: true }),
+ getHostingUser: async () => Promise.resolve(sampleUser as User),
+ getReservableShips: async () =>
+ Promise.resolve([
+ { id: '~solfer-magfed', readyForDistribution: true },
+ ]),
+ getShipAccessCode: async () => Promise.resolve({ code: 'xyz' }),
+ allocateReservedShip: async () => Promise.resolve({}),
+ getShipsWithStatus: async () =>
+ Promise.resolve({
+ shipId: '~solfer-magfed',
+ status: 'Ready',
+ }),
+ reserveShip: async () =>
+ Promise.resolve({
+ id: '~solfer-magfed',
+ reservedBy: '1',
+ }),
+ checkPhoneVerify: async () => Promise.resolve({ verified: true }),
+ verifyEmailDigits: async () => Promise.resolve({ verified: true }),
+ requestPhoneVerify: async () => Promise.resolve({}),
+ },
+ }}
+ >
+ void,
+ clearLure: () => setLure(undefined),
+ clearDeepLink: () => {},
+ deepLinkPath: undefined,
+ priorityToken: undefined,
+ }}
+ >
+
+ {children ?? }
+
+
+
+
+ );
+}
+
+function SingleScreenFixture({
+ routeName,
+ params,
+ Component,
+}: {
+ routeName: T;
+ params?: OnboardingStackParamList[T];
+ Component: React.ComponentType;
+}) {
+ return (
+
+
+
+
+
+ );
+}
+
+export default {
+ Stack: (
+
+
+
+ ),
+ StackWithGroupInvite: (
+
+
+
+ ),
+ Nickname: (
+
+ ),
+ Password: (
+
+ ),
+ JoinWaitlist: (
+
+ ),
+ RequestPhoneVerify: (
+
+ ),
+ CheckVerify: (
+
+ ),
+ ReserveShip: (
+
+ ),
+ SetNickname: (
+
+ ),
+ SetTelemetry: (
+
+ ),
+ Welcome: (
+
+ ),
+ InventoryCheck: (
+
+ ),
+ SignUpEmail: (
+
+ ),
+ EULA: ,
+ PasteInviteLink: (
+
+ ),
+ TlonLogin: (
+
+ ),
+ ShipLogin: (
+
+ ),
+};
diff --git a/apps/tlon-mobile/src/fixtures/PostScreen.fixture.tsx b/apps/tlon-mobile/src/fixtures/PostScreen.fixture.tsx
index 6c35fe4861..9a81df5f73 100644
--- a/apps/tlon-mobile/src/fixtures/PostScreen.fixture.tsx
+++ b/apps/tlon-mobile/src/fixtures/PostScreen.fixture.tsx
@@ -20,6 +20,7 @@ export default (
>
{}}
+ isLoadingPosts={false}
editPost={async () => {}}
onPressRetry={() => {}}
onPressDelete={() => {}}
diff --git a/apps/tlon-mobile/src/fixtures/SetNicknameScreen.fixture.tsx b/apps/tlon-mobile/src/fixtures/SetNicknameScreen.fixture.tsx
new file mode 100644
index 0000000000..1d2ea0911f
--- /dev/null
+++ b/apps/tlon-mobile/src/fixtures/SetNicknameScreen.fixture.tsx
@@ -0,0 +1,34 @@
+import { NavigationContainer } from '@react-navigation/native';
+import { NativeStackNavigationProp } from '@react-navigation/native-stack';
+
+import { SetNicknameScreen } from '../screens/Onboarding/SetNicknameScreen';
+import { OnboardingStackParamList, User } from '../types';
+import { FixtureWrapper } from './FixtureWrapper';
+
+const GroupMetaScreenFixture = () => {
+ const mockNavigation = {
+ navigate: () => {},
+ goBack: () => {},
+ addListener: () => {},
+ } as unknown as NativeStackNavigationProp<
+ OnboardingStackParamList,
+ 'SetNickname'
+ >;
+
+ return (
+
+
+
+
+
+ );
+};
+
+export default GroupMetaScreenFixture;
diff --git a/apps/tlon-mobile/src/fixtures/fakeData.ts b/apps/tlon-mobile/src/fixtures/fakeData.ts
index 383f724db5..27c2967f98 100644
--- a/apps/tlon-mobile/src/fixtures/fakeData.ts
+++ b/apps/tlon-mobile/src/fixtures/fakeData.ts
@@ -571,7 +571,7 @@ export const group: db.Group = {
coverImage: null,
coverImageColor: '#000000',
iconImage: 'https://tlon.io/local-icon.svg',
- iconImageColor: '#FFFFFF',
+ iconImageColor: '#000000',
currentUserIsMember: true,
lastPostAt: null,
lastPostId: null,
diff --git a/apps/tlon-mobile/src/lib/OnboardingContext.tsx b/apps/tlon-mobile/src/lib/OnboardingContext.tsx
new file mode 100644
index 0000000000..790d5c028c
--- /dev/null
+++ b/apps/tlon-mobile/src/lib/OnboardingContext.tsx
@@ -0,0 +1,26 @@
+import {
+ RecaptchaAction,
+ execute,
+ initClient,
+} from '@google-cloud/recaptcha-enterprise-react-native';
+import * as hostingApi from '@tloncorp/app/lib/hostingApi';
+import { getLandscapeAuthCookie } from '@tloncorp/shared/dist/api';
+import { createContext, useContext } from 'react';
+
+interface OnboardingContextValue {
+ hostingApi: typeof hostingApi;
+ initRecaptcha: typeof initClient;
+ execRecaptchaLogin: () => Promise;
+ getLandscapeAuthCookie: typeof getLandscapeAuthCookie;
+}
+
+export const OnboardingContext = createContext({
+ initRecaptcha: initClient,
+ execRecaptchaLogin: () => execute(RecaptchaAction.LOGIN(), 10_000),
+ getLandscapeAuthCookie,
+ hostingApi,
+});
+
+export const OnboardingProvider = OnboardingContext.Provider;
+
+export const useOnboardingContext = () => useContext(OnboardingContext);
diff --git a/apps/tlon-mobile/src/screens/Onboarding/CheckVerifyScreen.tsx b/apps/tlon-mobile/src/screens/Onboarding/CheckVerifyScreen.tsx
index 963c57ccba..3079822b90 100644
--- a/apps/tlon-mobile/src/screens/Onboarding/CheckVerifyScreen.tsx
+++ b/apps/tlon-mobile/src/screens/Onboarding/CheckVerifyScreen.tsx
@@ -1,27 +1,19 @@
import type { NativeStackScreenProps } from '@react-navigation/native-stack';
-import {
- checkPhoneVerify,
- requestPhoneVerify,
- resendEmailVerification,
- verifyEmailDigits,
-} from '@tloncorp/app/lib/hostingApi';
import { trackError, trackOnboardingAction } from '@tloncorp/app/utils/posthog';
-import { formatPhoneNumber } from '@tloncorp/app/utils/string';
import {
- Button,
Field,
ScreenHeader,
- SizableText,
- Text,
TextInput,
+ TlonText,
View,
XStack,
YStack,
} from '@tloncorp/ui';
-import { createRef, useMemo, useState } from 'react';
+import { createRef, useCallback, useMemo, useState } from 'react';
import type { TextInputKeyPressEventData } from 'react-native';
import { TextInput as RNTextInput } from 'react-native';
+import { useOnboardingContext } from '../../lib/OnboardingContext';
import type { OnboardingStackParamList } from '../../types';
type Props = NativeStackScreenProps;
@@ -40,77 +32,53 @@ export const CheckVerifyScreen = ({
const [code, setCode] = useState([]);
const [isSubmitting, setIsSubmitting] = useState(false);
const [error, setError] = useState();
- const inputRefs = useMemo(
- () =>
- Array.from({ length: codeLength }).map(() => createRef()),
- []
- );
+ const { hostingApi } = useOnboardingContext();
- const handleKeyPress = async (
- index: number,
- key: TextInputKeyPressEventData['key']
- ) => {
- if (key === 'Backspace' && !code[index] && index > 0) {
- inputRefs[index - 1].current?.focus();
- }
- };
-
- const handleChangeText = (index: number, text: string) => {
- const nextCode = [...code];
- if (text.length === 0) {
- nextCode[index] = '';
- } else {
- for (let i = 0; i < text.length; i += 1) {
- nextCode[index + i] = text.charAt(i);
- }
- }
+ const handleSubmit = useCallback(
+ async (code: string) => {
+ setIsSubmitting(true);
- if (nextCode.length === codeLength && nextCode.every(Boolean)) {
- handleSubmit(nextCode.join(''));
- } else if (index < inputRefs.length - 1 && nextCode[index]) {
- for (let i = index + 1; i < inputRefs.length; i += 1) {
- if (!nextCode[i]) {
- inputRefs[i].current?.focus();
- break;
+ try {
+ if (isEmail) {
+ await hostingApi.verifyEmailDigits(user.email, code);
+ } else {
+ await hostingApi.checkPhoneVerify(user.id, code);
}
- }
- }
-
- setCode(nextCode.slice(0, codeLength));
- };
- const handleSubmit = async (code: string) => {
- setIsSubmitting(true);
+ trackOnboardingAction({
+ actionName: 'Verification Submitted',
+ });
- try {
- if (isEmail) {
- await verifyEmailDigits(user.email, code);
- } else {
- await checkPhoneVerify(user.id, code);
+ navigation.navigate('ReserveShip', { user });
+ } catch (err) {
+ console.error('Error submitting verification:', err);
+ if (err instanceof Error) {
+ setError(err.message);
+ trackError(err);
+ }
}
- trackOnboardingAction({
- actionName: 'Verification Submitted',
- });
+ setIsSubmitting(false);
+ },
+ [hostingApi, isEmail, navigation, user]
+ );
- navigation.navigate('ReserveShip', { user });
- } catch (err) {
- console.error('Error submitting verification:', err);
- if (err instanceof Error) {
- setError(err.message);
- trackError(err);
+ const handleCodeChanged = useCallback(
+ (nextCode: string[]) => {
+ setCode(nextCode);
+ if (nextCode.length === codeLength && nextCode.every(Boolean)) {
+ handleSubmit(nextCode.join(''));
}
- }
-
- setIsSubmitting(false);
- };
+ },
+ [codeLength, handleSubmit]
+ );
const handleResend = async () => {
try {
if (isEmail) {
- await resendEmailVerification(user.id);
+ await hostingApi.resendEmailVerification(user.id);
} else {
- await requestPhoneVerify(user.id, user.phoneNumber ?? '');
+ await hostingApi.requestPhoneVerify(user.id, user.phoneNumber ?? '');
}
} catch (err) {
console.error('Error resending verification code:', err);
@@ -122,43 +90,104 @@ export const CheckVerifyScreen = ({
};
return (
-
+
navigation.goBack()}
isLoading={isSubmitting}
/>
-
-
- We’ve sent a confirmation code to{' '}
- {isEmail ? user.email : formatPhoneNumber(user.phoneNumber ?? '')}.
-
-
-
- {Array.from({ length: codeLength }).map((_, i) => (
-
- handleKeyPress(i, nativeEvent.key)
- }
- onChangeText={(text) => handleChangeText(i, text)}
- value={code.length > i ? code[i] : ''}
- keyboardType="numeric"
- maxLength={1}
- />
- ))}
-
-
-
- Didn’t receive a code?
-
-
+
+
+
+ Request a new code
+
);
};
+
+function CodeInput({
+ length,
+ value,
+ onChange,
+ error,
+}: {
+ length: number;
+ value: string[];
+ onChange?: (value: string[]) => void;
+ error?: string;
+}) {
+ const inputRefs = useMemo(
+ () => Array.from({ length }).map(() => createRef()),
+ [length]
+ );
+
+ const handleChangeText = useCallback(
+ (index: number, text: string) => {
+ const nextCode = [...value];
+ if (text.length === 0) {
+ nextCode[index] = '';
+ } else {
+ for (let i = 0; i < text.length; i += 1) {
+ nextCode[index + i] = text.charAt(i);
+ }
+ }
+ if (index < inputRefs.length - 1 && nextCode[index]) {
+ for (let i = index + 1; i < inputRefs.length; i += 1) {
+ if (!nextCode[i]) {
+ inputRefs[i].current?.focus();
+ break;
+ }
+ }
+ }
+ onChange?.(nextCode.slice(0, length));
+ },
+ [onChange, value, inputRefs, length]
+ );
+
+ const handleKeyPress = async (
+ index: number,
+ key: TextInputKeyPressEventData['key']
+ ) => {
+ if (key === 'Backspace' && !value[index] && index > 0) {
+ inputRefs[index - 1].current?.focus();
+ }
+ };
+
+ return (
+
+
+ {Array.from({ length }).map((_, i) => (
+ handleKeyPress(i, nativeEvent.key)}
+ placeholder="5"
+ onChangeText={(text) => handleChangeText(i, text)}
+ value={value.length > i ? value[i] : ''}
+ keyboardType="numeric"
+ paddingHorizontal="$xl"
+ paddingVertical="$xl"
+ width="$4xl"
+ />
+ ))}
+
+
+ );
+}
diff --git a/apps/tlon-mobile/src/screens/Onboarding/EULAScreen.tsx b/apps/tlon-mobile/src/screens/Onboarding/EULAScreen.tsx
index 01d237c9e8..fda895295d 100644
--- a/apps/tlon-mobile/src/screens/Onboarding/EULAScreen.tsx
+++ b/apps/tlon-mobile/src/screens/Onboarding/EULAScreen.tsx
@@ -8,7 +8,7 @@ type Props = NativeStackScreenProps;
export const EULAScreen = ({ navigation }: Props) => {
return (
-
+
;
@@ -22,19 +22,20 @@ type Props = NativeStackScreenProps;
export const InventoryCheckScreen = ({ navigation }: Props) => {
const signupParams = useSignupParams();
const [isChecking, setIsChecking] = useState(false);
+ const { hostingApi } = useOnboardingContext();
const checkAvailability = async () => {
setIsChecking(true);
try {
- const { enabled } = await getHostingAvailability({
+ const { enabled } = await hostingApi.getHostingAvailability({
lure: signupParams.lureId,
priorityToken: signupParams.priorityToken,
});
if (enabled) {
navigation.navigate('SignUpEmail');
} else {
- navigation.navigate('InviteLink');
+ navigation.navigate('PasteInviteLink');
}
} catch (err) {
console.error('Error checking hosting availability:', err);
@@ -49,7 +50,7 @@ export const InventoryCheckScreen = ({ navigation }: Props) => {
return (
navigation.goBack()}
isLoading={isChecking}
@@ -57,11 +58,7 @@ export const InventoryCheckScreen = ({ navigation }: Props) => {
-
+
diff --git a/apps/tlon-mobile/src/screens/Onboarding/InviteLinkScreen.tsx b/apps/tlon-mobile/src/screens/Onboarding/InviteLinkScreen.tsx
deleted file mode 100644
index 1967b29c9d..0000000000
--- a/apps/tlon-mobile/src/screens/Onboarding/InviteLinkScreen.tsx
+++ /dev/null
@@ -1,155 +0,0 @@
-import Clipboard from '@react-native-clipboard/clipboard';
-import type { NativeStackScreenProps } from '@react-navigation/native-stack';
-import { BRANCH_DOMAIN, BRANCH_KEY } from '@tloncorp/app/constants';
-import { useBranch, useLureMetadata } from '@tloncorp/app/contexts/branch';
-import {
- DeepLinkData,
- createInviteLinkRegex,
- extractNormalizedInviteLink,
- getMetadaFromInviteLink,
-} from '@tloncorp/shared/dist';
-import {
- AppInviteDisplay,
- Field,
- PrimaryButton,
- ScreenHeader,
- SizableText,
- TextInputWithButton,
- View,
- YStack,
-} from '@tloncorp/ui';
-import { useCallback, useEffect, useState } from 'react';
-import { Controller, useForm } from 'react-hook-form';
-import { Keyboard } from 'react-native';
-
-import type { OnboardingStackParamList } from '../../types';
-
-const INVITE_LINK_REGEX = createInviteLinkRegex(BRANCH_DOMAIN);
-
-type Props = NativeStackScreenProps;
-
-type FormData = {
- inviteLink: string;
-};
-
-export const InviteLinkScreen = ({ navigation }: Props) => {
- const lureMeta = useLureMetadata();
- const { setLure } = useBranch();
- const [hasInvite, setHasInvite] = useState(Boolean(lureMeta));
-
- const {
- control,
- formState: { errors },
- setValue,
- watch,
- trigger,
- } = useForm();
-
- // watch for changes to the input & check for valid invite links
- const inviteLinkValue = watch('inviteLink');
- useEffect(() => {
- async function handleInviteLinkChange() {
- const extractedLink = extractNormalizedInviteLink(
- inviteLinkValue,
- BRANCH_DOMAIN
- );
- if (extractedLink) {
- const inviteLinkMeta = await getMetadaFromInviteLink(
- extractedLink,
- BRANCH_KEY
- );
- if (inviteLinkMeta) {
- setLure(inviteLinkMeta as DeepLinkData);
- return;
- }
- }
- trigger('inviteLink');
- }
- handleInviteLinkChange();
- }, [inviteLinkValue, setLure, trigger]);
-
- // if at any point we have invite metadata, notify & allow them to proceed
- // to signup
- useEffect(() => {
- if (lureMeta) {
- setHasInvite(true);
- }
- }, [lureMeta]);
-
- // handle paste button click
- const onHandlePasteClick = useCallback(async () => {
- const clipboardContents = await Clipboard.getString();
- setValue('inviteLink', clipboardContents);
- }, [setValue]);
-
- return (
-
- navigation.goBack()}
- />
- Keyboard.dismiss()}
- flex={1}
- >
- {!hasInvite ? (
- <>
-
-
- We're growing slowly. Invites let you skip the waitlist
- because we know someone wants to talk to you here.
-
-
- Click your invite link now or paste it below.
-
-
- (
-
-
-
- )}
- />
-
- navigation.navigate('JoinWaitList', {})}
- >
- I don't have an invite
-
- >
- ) : (
- <>
-
- Invite found!
-
-
- navigation.navigate('SignUpEmail')}>
- Sign up
-
- >
- )}
-
-
- );
-};
diff --git a/apps/tlon-mobile/src/screens/Onboarding/JoinWaitListScreen.tsx b/apps/tlon-mobile/src/screens/Onboarding/JoinWaitListScreen.tsx
index 93ca184470..a3240829c7 100644
--- a/apps/tlon-mobile/src/screens/Onboarding/JoinWaitListScreen.tsx
+++ b/apps/tlon-mobile/src/screens/Onboarding/JoinWaitListScreen.tsx
@@ -4,15 +4,15 @@ import { addUserToWaitlist } from '@tloncorp/app/lib/hostingApi';
import { trackError, trackOnboardingAction } from '@tloncorp/app/utils/posthog';
import {
Field,
- PrimaryButton,
ScreenHeader,
- SizableText,
TextInput,
+ TlonText,
View,
YStack,
} from '@tloncorp/ui';
import { useState } from 'react';
import { Controller, useForm } from 'react-hook-form';
+import { Alert } from 'react-native';
import type { OnboardingStackParamList } from '../../types';
@@ -36,9 +36,15 @@ export const JoinWaitListScreen = ({ navigation }: Props) => {
trackOnboardingAction({
actionName: 'Waitlist Joined',
});
- navigation.popToTop();
+ Alert.alert('Success', 'You have been added to the waitlist.', [
+ {
+ text: 'OK',
+ onPress: () => navigation.popToTop(),
+ },
+ ]);
} catch (err) {
console.error('Error joining waitlist:', err);
+ Alert.alert('Failed', 'Unable to add you to the waitlist.');
if (err instanceof Error) {
setRemoteError(err.message);
trackError(err);
@@ -47,18 +53,26 @@ export const JoinWaitListScreen = ({ navigation }: Props) => {
};
return (
-
+
navigation.goBack()}
+ rightControls={
+
+ Submit
+
+ }
/>
-
-
- We’ve given out all available accounts for today, but
- we’ll have more soon. If you’d like, we can let you know
- via email when they’re ready.
-
+
+
+
+ We’ll let you know as soon as space is available.
+
+
{
},
}}
render={({ field: { onChange, onBlur, value } }) => (
-
+
{
)}
/>
{remoteError ? (
-
+
{remoteError}
-
+
) : null}
-
- {isValid && (
-
- Notify Me
-
- )}
-
);
diff --git a/apps/tlon-mobile/src/screens/Onboarding/PasteInviteLinkScreen.tsx b/apps/tlon-mobile/src/screens/Onboarding/PasteInviteLinkScreen.tsx
new file mode 100644
index 0000000000..e72dd8222a
--- /dev/null
+++ b/apps/tlon-mobile/src/screens/Onboarding/PasteInviteLinkScreen.tsx
@@ -0,0 +1,180 @@
+import Clipboard from '@react-native-clipboard/clipboard';
+import type { NativeStackScreenProps } from '@react-navigation/native-stack';
+import {
+ BRANCH_DOMAIN,
+ BRANCH_KEY,
+ DEFAULT_INVITE_LINK_URL,
+} from '@tloncorp/app/constants';
+import { useBranch, useLureMetadata } from '@tloncorp/app/contexts/branch';
+import { trackError, trackOnboardingAction } from '@tloncorp/app/utils/posthog';
+import {
+ DeepLinkData,
+ createInviteLinkRegex,
+ extractNormalizedInviteLink,
+ getMetadaFromInviteLink,
+} from '@tloncorp/shared/dist';
+import {
+ Field,
+ ScreenHeader,
+ TextInputWithButton,
+ TlonText,
+ View,
+ YStack,
+} from '@tloncorp/ui';
+import { useCallback, useEffect, useState } from 'react';
+import { Controller, useForm } from 'react-hook-form';
+import { Keyboard } from 'react-native';
+
+import type { OnboardingStackParamList } from '../../types';
+
+const INVITE_LINK_REGEX = createInviteLinkRegex(BRANCH_DOMAIN);
+
+type Props = NativeStackScreenProps<
+ OnboardingStackParamList,
+ 'PasteInviteLink'
+>;
+
+type FormData = {
+ inviteLink: string;
+};
+
+export const PasteInviteLinkScreen = ({ navigation }: Props) => {
+ const lureMeta = useLureMetadata();
+ const { setLure } = useBranch();
+
+ const {
+ control,
+ formState: { errors },
+ setValue,
+ watch,
+ trigger,
+ } = useForm({
+ defaultValues: {
+ inviteLink: DEFAULT_INVITE_LINK_URL,
+ },
+ });
+
+ const [metadataError, setMetadataError] = useState(null);
+
+ // watch for changes to the input & check for valid invite links
+ const inviteLinkValue = watch('inviteLink');
+ useEffect(() => {
+ async function handleInviteLinkChange() {
+ const extractedLink = extractNormalizedInviteLink(
+ inviteLinkValue,
+ BRANCH_DOMAIN
+ );
+ setMetadataError(null);
+ if (extractedLink) {
+ try {
+ const inviteLinkMeta = await getMetadaFromInviteLink(
+ extractedLink,
+ BRANCH_KEY
+ );
+ if (inviteLinkMeta) {
+ setLure(inviteLinkMeta as DeepLinkData);
+ return;
+ } else {
+ throw new Error('Failed to retrieve invite metadata');
+ }
+ } catch (e) {
+ trackError({
+ message: e.message,
+ properties: {
+ inviteLink: extractedLink,
+ branchDomain: BRANCH_DOMAIN,
+ branchKey: BRANCH_KEY,
+ },
+ });
+ setMetadataError('Unable to load invite');
+ }
+ }
+ trigger('inviteLink');
+ }
+ handleInviteLinkChange();
+ }, [inviteLinkValue, setLure, trigger]);
+
+ // if at any point we have invite metadata, notify & allow them to proceed
+ // to signup
+ useEffect(() => {
+ if (lureMeta) {
+ trackOnboardingAction({
+ actionName: 'Invite Link Added',
+ lure: lureMeta.id,
+ });
+
+ navigation.reset({
+ index: 0,
+ routes: [{ name: 'Welcome' }, { name: 'SignUpEmail' }],
+ });
+ }
+ }, [lureMeta, navigation]);
+
+ // handle paste button click
+ const onHandlePasteClick = useCallback(async () => {
+ const clipboardContents = await Clipboard.getString();
+ setValue('inviteLink', clipboardContents);
+ }, [setValue]);
+
+ return (
+
+ navigation.goBack()}
+ rightControls={
+ navigation.navigate('SignUpEmail')}
+ >
+ Next
+
+ }
+ />
+ Keyboard.dismiss()}
+ flex={1}
+ >
+
+
+ We're growing slowly. {'\n\n'}Invites let you skip the waitlist
+ because we know someone wants to talk to you here.
+ {'\n\n'}
+ Click your invite link now or paste it below.
+
+
+ (
+
+
+
+ )}
+ />
+
+
+ );
+};
diff --git a/apps/tlon-mobile/src/screens/Onboarding/RequestPhoneVerifyScreen.tsx b/apps/tlon-mobile/src/screens/Onboarding/RequestPhoneVerifyScreen.tsx
index 46f5bbf06b..2886f7f15e 100644
--- a/apps/tlon-mobile/src/screens/Onboarding/RequestPhoneVerifyScreen.tsx
+++ b/apps/tlon-mobile/src/screens/Onboarding/RequestPhoneVerifyScreen.tsx
@@ -4,8 +4,9 @@ import { requestPhoneVerify } from '@tloncorp/app/lib/hostingApi';
import { trackError, trackOnboardingAction } from '@tloncorp/app/utils/posthog';
import {
Field,
+ OnboardingTextBlock,
ScreenHeader,
- SizableText,
+ TlonText,
View,
YStack,
useTheme,
@@ -75,7 +76,7 @@ export const RequestPhoneVerifyScreen = ({
});
return (
-
+
}
/>
-
-
- Tlon is a platform for humans. We want to make sure you’re one
- too. We’ll send you a verification code to the phone number you
- enter below.
-
- {remoteError ? (
-
- {remoteError}
-
- ) : null}
-
+
+
+
+ Tlon is a platform for humans. We want to make sure you’re one
+ too. We’ll send you a verification code to the phone number
+ you enter below.
+
+ {remoteError ? (
+
+ {remoteError}
+
+ ) : null}
+
+
+
;
@@ -35,13 +25,15 @@ export const ReserveShipScreen = ({
}>({
state: 'loading',
});
+ const { hostingApi, getLandscapeAuthCookie } = useOnboardingContext();
const signupContext = useSignupContext();
const { setShip } = useShip();
const startShip = useCallback(
async (shipIds: string[]) => {
// Fetch statuses for the user's ships and start any required booting/resuming
- const shipsWithStatus = await getShipsWithStatus(shipIds);
+ const shipsWithStatus = await hostingApi.getShipsWithStatus(shipIds);
+ console.log('shipsWithStatus', shipsWithStatus);
if (!shipsWithStatus) {
// you can only have gotten to this screen if a new hosting account was created and ship
// was reserved. If we don't see the ship status, assume it's still booting
@@ -56,7 +48,7 @@ export const ReserveShipScreen = ({
signupContext.telemetry === undefined
) {
return navigation.navigate('SetNickname', {
- user: await getHostingUser(user.id),
+ user: await hostingApi.getHostingUser(user.id),
});
}
@@ -66,7 +58,7 @@ export const ReserveShipScreen = ({
}
// If it's ready, fetch the access code and auth cookie
- const { code: accessCode } = await getShipAccessCode(shipId);
+ const { code: accessCode } = await hostingApi.getShipAccessCode(shipId);
const shipUrl = getShipUrl(shipId);
const authCookie = await getLandscapeAuthCookie(shipUrl, accessCode);
if (!authCookie) {
@@ -87,6 +79,8 @@ export const ReserveShipScreen = ({
});
},
[
+ getLandscapeAuthCookie,
+ hostingApi,
navigation,
setShip,
signupContext.nickname,
@@ -103,7 +97,7 @@ export const ReserveShipScreen = ({
if (shipIds.length === 0) {
try {
// Get list of reservable ships and choose one that's ready for distribution
- const ships = await getReservableShips(user.id);
+ const ships = await hostingApi.getReservableShips(user.id);
const ship = ships.find(
({ id, readyForDistribution }) =>
id !== skipShipId && readyForDistribution
@@ -117,13 +111,14 @@ export const ReserveShipScreen = ({
}
// Reserve this ship and check it was successful
- const { reservedBy } = await reserveShipApi(user.id, ship.id);
+ const { reservedBy } = await hostingApi.reserveShip(user.id, ship.id);
+ console.log('reserved', user, reservedBy);
if (reservedBy !== user.id) {
return reserveShip(ship.id);
}
// Finish allocating this ship to the user
- await allocateReservedShip(user.id);
+ await hostingApi.allocateReservedShip(user.id);
shipIds.push(ship.id);
trackOnboardingAction({
actionName: 'Urbit ID Selected',
diff --git a/apps/tlon-mobile/src/screens/Onboarding/SetNicknameScreen.tsx b/apps/tlon-mobile/src/screens/Onboarding/SetNicknameScreen.tsx
index bc35e9952a..8e789ce9ec 100644
--- a/apps/tlon-mobile/src/screens/Onboarding/SetNicknameScreen.tsx
+++ b/apps/tlon-mobile/src/screens/Onboarding/SetNicknameScreen.tsx
@@ -4,11 +4,14 @@ import { requestNotificationToken } from '@tloncorp/app/lib/notifications';
import { trackError } from '@tloncorp/app/utils/posthog';
import {
Field,
+ Image,
ScreenHeader,
- SizableText,
TextInput,
+ TlonText,
View,
+ XStack,
YStack,
+ useTheme,
} from '@tloncorp/ui';
import { useEffect } from 'react';
import { Controller, useForm } from 'react-hook-form';
@@ -28,10 +31,16 @@ export const SetNicknameScreen = ({
params: { user },
},
}: Props) => {
+ const theme = useTheme();
+
+ const facesImage = theme.dark
+ ? require('../../../assets/images/faces-dark.png')
+ : require('../../../assets/images/faces.png');
+
const {
control,
handleSubmit,
- formState: { errors },
+ formState: { errors, isValid },
setValue,
} = useForm({
defaultValues: {
@@ -82,29 +91,40 @@ export const SetNicknameScreen = ({
}, [setValue]);
return (
-
+
+
Next
}
/>
-
-
+
+
+
+
+
+
Choose the nickname you want to use on the Tlon network. By default,
you will use a pseudonymous identifier.
-
+
(
-
-
-
- We’re trying to make the app better and knowing how people use
- the app really helps.
-
+
+
+ Next
+
+ }
+ />
+
+
+
+ We’re trying to make the app better and knowing how people use
+ the app really helps.
+
+
+ These stats are anonymous, for product development purposes only,
+ and we don’t share them with anyone.
+
+
+
- Next
);
diff --git a/apps/tlon-mobile/src/screens/Onboarding/ShipLoginScreen.tsx b/apps/tlon-mobile/src/screens/Onboarding/ShipLoginScreen.tsx
index 84d6f2093f..28b35f10e9 100644
--- a/apps/tlon-mobile/src/screens/Onboarding/ShipLoginScreen.tsx
+++ b/apps/tlon-mobile/src/screens/Onboarding/ShipLoginScreen.tsx
@@ -5,22 +5,20 @@ import {
DEFAULT_SHIP_LOGIN_URL,
} from '@tloncorp/app/constants';
import { useShip } from '@tloncorp/app/contexts/ship';
-import { isEulaAgreed, setEulaAgreed } from '@tloncorp/app/utils/eula';
import { getShipFromCookie } from '@tloncorp/app/utils/ship';
import { transformShipURL } from '@tloncorp/app/utils/string';
import { getLandscapeAuthCookie } from '@tloncorp/shared/dist/api';
import {
- CheckboxInput,
Field,
- Icon,
KeyboardAvoidingView,
- ListItem,
+ OnboardingTextBlock,
ScreenHeader,
- SizableText,
TextInput,
+ TlonText,
View,
YStack,
} from '@tloncorp/ui';
+import { setEulaAgreed } from '@tloncorp/app/utils/eula';
import { useCallback, useEffect, useState } from 'react';
import { Controller, useForm } from 'react-hook-form';
@@ -47,7 +45,6 @@ export const ShipLoginScreen = ({ navigation }: Props) => {
formState: { errors, isValid },
setValue,
trigger,
- watch,
} = useForm({
defaultValues: {
shipUrl: DEFAULT_SHIP_LOGIN_URL,
@@ -70,17 +67,15 @@ export const ShipLoginScreen = ({ navigation }: Props) => {
return true;
}, []);
- const handleEula = () => {
+ const handlePressEula = useCallback(() => {
navigation.navigate('EULA');
- };
+ }, [navigation]);
const onSubmit = handleSubmit(async (params) => {
const { shipUrl: rawShipUrl, accessCode } = params;
setIsSubmitting(true);
- if (params.eulaAgreed) {
- await setEulaAgreed();
- }
+ setEulaAgreed();
const shipUrl = transformShipURL(rawShipUrl);
setFormattedShipUrl(shipUrl);
@@ -91,17 +86,11 @@ export const ShipLoginScreen = ({ navigation }: Props) => {
);
if (authCookie) {
const shipId = getShipFromCookie(authCookie);
- if (await isEulaAgreed()) {
- setShip({
- ship: shipId,
- shipUrl,
- authCookie,
- });
- } else {
- setRemoteError(
- 'Please agree to the End User License Agreement to continue.'
- );
- }
+ setShip({
+ ship: shipId,
+ shipUrl,
+ authCookie,
+ });
} else {
setRemoteError(
"Sorry, we couldn't log in to your ship. It may be busy or offline."
@@ -129,114 +118,112 @@ export const ShipLoginScreen = ({ navigation }: Props) => {
backAction={() => navigation.goBack()}
isLoading={isSubmitting}
rightControls={
- isValid &&
- watch('eulaAgreed') && (
-
- Connect
-
- )
+
+ Connect
+
}
/>
-
-
- Connect a self-hosted ship by entering its URL and access code.
-
- {remoteError ? (
- {remoteError}
- ) : null}
-
- {
- const urlValidation = isValidUrl(value);
- if (urlValidation === false) {
- return 'Please enter a valid URL.';
- }
- if (urlValidation === 'hosted') {
- return 'Please log in to your hosted Tlon ship using email and password.';
- }
- return true;
- },
- }}
- render={({ field: { onChange, onBlur, value } }) => (
-
- {
- onBlur();
- trigger('shipUrl');
- }}
- onChangeText={onChange}
- onSubmitEditing={() => setFocus('accessCode')}
- value={value}
- keyboardType="url"
- autoCapitalize="none"
- autoCorrect={false}
- returnKeyType="next"
- enablesReturnKeyAutomatically
- />
-
- )}
- />
- (
-
- {
- onBlur();
- trigger('accessCode');
- }}
- onChangeText={onChange}
- onSubmitEditing={onSubmit}
- value={value}
- secureTextEntry
- autoCapitalize="none"
- autoCorrect={false}
- returnKeyType="send"
- enablesReturnKeyAutomatically
- />
-
- )}
- />
- (
-
+
+
+ Connect a self-hosted ship by entering its URL and access code.
+
+ {remoteError ? (
+
+ {remoteError}
+
+ ) : null}
+
+
+ {
+ const urlValidation = isValidUrl(value);
+ if (urlValidation === false) {
+ return 'Please enter a valid URL.';
+ }
+ if (urlValidation === 'hosted') {
+ return 'Please log in to your hosted Tlon ship using email and password.';
+ }
+ return true;
+ },
+ }}
+ render={({ field: { onChange, onBlur, value } }) => (
+
+ {
+ onBlur();
+ trigger('shipUrl');
+ }}
+ onChangeText={onChange}
+ onSubmitEditing={() => setFocus('accessCode')}
+ value={value}
+ keyboardType="url"
+ autoCapitalize="none"
+ autoCorrect={false}
+ returnKeyType="next"
+ enablesReturnKeyAutomatically
+ />
+
+ )}
+ />
+ (
+
+ {
+ onBlur();
+ trigger('accessCode');
+ }}
+ onChangeText={onChange}
+ onSubmitEditing={onSubmit}
+ value={value}
+ secureTextEntry
+ autoCapitalize="none"
+ autoCorrect={false}
+ returnKeyType="send"
+ enablesReturnKeyAutomatically
+ />
+
+ )}
+ />
+
+
+
+ By logging in you agree to Tlon’s{' '}
+ onChange(!value)}
- />
- )}
- />
-
-
- End User License Agreement
-
-
-
-
-
+ textDecorationLine="underline"
+ textDecorationDistance={10}
+ onPress={handlePressEula}
+ >
+ Terms of Service
+
+
+
diff --git a/apps/tlon-mobile/src/screens/Onboarding/SignUpEmailScreen.tsx b/apps/tlon-mobile/src/screens/Onboarding/SignUpEmailScreen.tsx
index 7a45acf8bd..03b2689b71 100644
--- a/apps/tlon-mobile/src/screens/Onboarding/SignUpEmailScreen.tsx
+++ b/apps/tlon-mobile/src/screens/Onboarding/SignUpEmailScreen.tsx
@@ -4,14 +4,12 @@ import {
useLureMetadata,
useSignupParams,
} from '@tloncorp/app/contexts/branch';
-import { getHostingAvailability } from '@tloncorp/app/lib/hostingApi';
import { trackError, trackOnboardingAction } from '@tloncorp/app/utils/posthog';
import {
- AppInviteDisplay,
Field,
KeyboardAvoidingView,
+ OnboardingInviteBlock,
ScreenHeader,
- SizableText,
TextInput,
View,
YStack,
@@ -19,6 +17,7 @@ import {
import { useState } from 'react';
import { Controller, useForm } from 'react-hook-form';
+import { useOnboardingContext } from '../../lib/OnboardingContext';
import type { OnboardingStackParamList } from '../../types';
type Props = NativeStackScreenProps;
@@ -29,6 +28,7 @@ type FormData = {
export const SignUpEmailScreen = ({ navigation, route: { params } }: Props) => {
const [isSubmitting, setIsSubmitting] = useState(false);
+ const { hostingApi } = useOnboardingContext();
const signupParams = useSignupParams();
const lureMeta = useLureMetadata();
@@ -45,7 +45,7 @@ export const SignUpEmailScreen = ({ navigation, route: { params } }: Props) => {
setIsSubmitting(true);
try {
- const { enabled, validEmail } = await getHostingAvailability({
+ const { enabled, validEmail } = await hostingApi.getHostingAvailability({
email,
lure: signupParams.lureId,
priorityToken: signupParams.priorityToken,
@@ -85,27 +85,21 @@ export const SignUpEmailScreen = ({ navigation, route: { params } }: Props) => {
});
return (
-
+
navigation.goBack()}
isLoading={isSubmitting}
rightControls={
- isValid && (
-
- Next
-
- )
+
+ Next
+
}
/>
-
- {lureMeta ? : null}
-
- Enter your email address. You’ll use it to log in to Tlon and
- we’ll email you the occasional service update.
-
+
+ {lureMeta ? : null}
{
},
}}
render={({ field: { onChange, onBlur, value } }) => (
-
+
{
onBlur();
trigger('email');
}}
+ backgroundColor={'$background'}
onChangeText={onChange}
onSubmitEditing={onSubmit}
value={value}
diff --git a/apps/tlon-mobile/src/screens/Onboarding/SignUpPasswordScreen.tsx b/apps/tlon-mobile/src/screens/Onboarding/SignUpPasswordScreen.tsx
index 81514a199c..3df706fa2e 100644
--- a/apps/tlon-mobile/src/screens/Onboarding/SignUpPasswordScreen.tsx
+++ b/apps/tlon-mobile/src/screens/Onboarding/SignUpPasswordScreen.tsx
@@ -1,37 +1,28 @@
-import {
- RecaptchaAction,
- execute,
- initClient,
-} from '@google-cloud/recaptcha-enterprise-react-native';
import type { NativeStackScreenProps } from '@react-navigation/native-stack';
import { RECAPTCHA_SITE_KEY } from '@tloncorp/app/constants';
-import {
- useLureMetadata,
- useSignupParams,
-} from '@tloncorp/app/contexts/branch';
+import { useSignupParams } from '@tloncorp/app/contexts/branch';
import { useSignupContext } from '@tloncorp/app/contexts/signup';
+import { setEulaAgreed } from '@tloncorp/app/utils/eula';
+import { trackOnboardingAction } from '@tloncorp/app/utils/posthog';
+import { createDevLogger } from '@tloncorp/shared';
import {
- logInHostingUser,
- signUpHostingUser,
-} from '@tloncorp/app/lib/hostingApi';
-import { isEulaAgreed, setEulaAgreed } from '@tloncorp/app/utils/eula';
-import { trackError, trackOnboardingAction } from '@tloncorp/app/utils/posthog';
-import {
- AppInviteDisplay,
- CheckboxInput,
+ Button,
Field,
- Icon,
KeyboardAvoidingView,
ListItem,
+ Modal,
ScreenHeader,
- SizableText,
TextInput,
+ TlonText,
View,
YStack,
} from '@tloncorp/ui';
-import { useEffect, useState } from 'react';
+import { useCallback, useEffect, useState } from 'react';
import { Controller, useForm } from 'react-hook-form';
+import { useWindowDimensions } from 'react-native';
+import { getTokenValue } from 'tamagui';
+import { useOnboardingContext } from '../../lib/OnboardingContext';
import type { OnboardingStackParamList } from '../../types';
type Props = NativeStackScreenProps;
@@ -42,6 +33,8 @@ type FormData = {
eulaAgreed: boolean;
};
+const logger = createDevLogger('SignUpPassword', true);
+
export const SignUpPasswordScreen = ({
navigation,
route: {
@@ -49,27 +42,30 @@ export const SignUpPasswordScreen = ({
},
}: Props) => {
const [isSubmitting, setIsSubmitting] = useState(false);
+ const [recaptchaError, setRecaptchaError] = useState(null);
+ const [recaptchaReInitError, setRecaptchaReInitError] =
+ useState(null);
const signupContext = useSignupContext();
const signupParams = useSignupParams();
- const lureMeta = useLureMetadata();
+ const { initRecaptcha, execRecaptchaLogin, hostingApi } =
+ useOnboardingContext();
const {
control,
setFocus,
handleSubmit,
formState: { errors, isValid },
setError,
- trigger,
- watch,
} = useForm({
defaultValues: {
eulaAgreed: false,
},
- mode: 'onChange',
+ mode: 'onBlur',
});
+ const { height } = useWindowDimensions();
- const handleEula = () => {
+ const handlePressEula = useCallback(() => {
navigation.navigate('EULA');
- };
+ }, [navigation]);
const onSubmit = handleSubmit(async (params) => {
const { password } = params;
@@ -77,38 +73,26 @@ export const SignUpPasswordScreen = ({
let recaptchaToken: string | undefined;
try {
- recaptchaToken = await execute(RecaptchaAction.LOGIN(), 10_000);
+ recaptchaToken = await execRecaptchaLogin();
} catch (err) {
console.error('Error executing reCAPTCHA:', err);
if (err instanceof Error) {
- setError('password', {
- type: 'custom',
- message: err.message,
+ setRecaptchaError(err);
+ logger.trackError('Error executing reCAPTCHA', {
+ thrownErrorMessage: err.message,
});
- trackError(err);
}
}
- if (params.eulaAgreed) {
- await setEulaAgreed();
- }
+ await setEulaAgreed();
- if (!recaptchaToken) {
- setIsSubmitting(false);
- return;
- }
-
- if (!isEulaAgreed()) {
- setError('eulaAgreed', {
- type: 'custom',
- message: 'Please agree to the End User License Agreement to continue.',
- });
+ if (!recaptchaToken || recaptchaError || recaptchaReInitError) {
setIsSubmitting(false);
return;
}
try {
- await signUpHostingUser({
+ await hostingApi.signUpHostingUser({
email,
password,
recaptchaToken,
@@ -123,7 +107,9 @@ export const SignUpPasswordScreen = ({
type: 'custom',
message: err.message,
});
- trackError(err);
+ logger.trackError('Error signing up user', {
+ thrownErrorMessage: err.message,
+ });
}
setIsSubmitting(false);
return;
@@ -136,7 +122,7 @@ export const SignUpPasswordScreen = ({
});
try {
- const user = await logInHostingUser({
+ const user = await hostingApi.logInHostingUser({
email,
password,
});
@@ -152,7 +138,9 @@ export const SignUpPasswordScreen = ({
type: 'custom',
message: err.message,
});
- trackError(err);
+ logger.trackError('Error logging in user', {
+ thrownErrorMessage: err.message,
+ });
}
}
@@ -163,128 +151,163 @@ export const SignUpPasswordScreen = ({
useEffect(() => {
(async () => {
try {
- await initClient(RECAPTCHA_SITE_KEY, 10_000);
+ await initRecaptcha(RECAPTCHA_SITE_KEY, 10_000);
} catch (err) {
console.error('Error initializing reCAPTCHA client:', err);
if (err instanceof Error) {
- setError('password', {
- type: 'custom',
- message: err.message,
+ setRecaptchaError(err);
+ logger.trackError('Error initializing reCAPTCHA client', {
+ thrownErrorMessage: err.message,
+ siteKey: RECAPTCHA_SITE_KEY,
});
- trackError(err);
}
}
})();
}, []);
+ // Re-initialize reCAPTCHA client if an error occurred
+ useEffect(() => {
+ if (recaptchaError && !recaptchaReInitError) {
+ (async () => {
+ try {
+ await initRecaptcha(RECAPTCHA_SITE_KEY, 10_000);
+ setRecaptchaError(null);
+ await onSubmit();
+ } catch (err) {
+ console.error('Error re-initializing reCAPTCHA client:', err);
+ if (err instanceof Error) {
+ logger.trackError('Error re-initializing reCAPTCHA client', {
+ thrownErrorMessage: err.message,
+ siteKey: RECAPTCHA_SITE_KEY,
+ });
+ setRecaptchaReInitError(err);
+ }
+ }
+ })();
+ }
+ }, [recaptchaError]);
+
return (
-
+
navigation.goBack()}
isLoading={isSubmitting}
rightControls={
- isValid &&
- watch('eulaAgreed') && (
-
- Next
-
- )
+
+ Next
+
}
/>
-
- {lureMeta ? : null}
-
- Please set a strong password with at least 8 characters.
-
- (
-
- {
- onBlur();
- trigger('password');
- }}
- onChangeText={onChange}
- onSubmitEditing={() => setFocus('confirmPassword')}
- value={value}
- secureTextEntry
- autoCapitalize="none"
- autoCorrect={false}
- returnKeyType="next"
- enablesReturnKeyAutomatically
- />
-
- )}
- />
-
- value === password || 'Passwords must match.',
- }}
- render={({ field: { onChange, onBlur, value } }) => (
-
- {
- onBlur();
- trigger('confirmPassword');
- }}
- onChangeText={onChange}
- onSubmitEditing={onSubmit}
- value={value}
- secureTextEntry
- autoCapitalize="none"
- autoCorrect={false}
- returnKeyType="send"
- enablesReturnKeyAutomatically
- />
-
- )}
- />
- (
-
+ {/* {lureMeta ? : null} */}
+
+
+ Please set a strong password with at least 8 characters.
+
+
+
+ (
+
+ setFocus('confirmPassword')}
+ value={value}
+ secureTextEntry
+ autoCapitalize="none"
+ autoCorrect={false}
+ returnKeyType="next"
+ enablesReturnKeyAutomatically
+ />
+
+ )}
+ />
+
+ value === password || 'Passwords must match.',
+ }}
+ render={({ field: { onChange, onBlur, value, ref } }) => (
+
+
+
+ )}
+ />
+
+
+
+ By registering you agree to Tlon’s{' '}
+ onChange(!value)}
- />
- )}
- />
-
-
- End User License Agreement
-
-
-
-
-
+ textDecorationLine="underline"
+ textDecorationDistance={10}
+ onPress={handlePressEula}
+ >
+ Terms of Service
+
+
+
+
+
+
+
+ We encountered an error reaching Google's reCAPTCHA service.
+
+
+ This may be due to a network issue or a problem with the service
+ itself.
+
+
+ A retry may resolve the issue. If the problem persists, please
+ contact support.
+
+
+
+
+
);
};
diff --git a/apps/tlon-mobile/src/screens/Onboarding/TlonLoginScreen.tsx b/apps/tlon-mobile/src/screens/Onboarding/TlonLoginScreen.tsx
index 56aa9e3b3e..aee9c307f1 100644
--- a/apps/tlon-mobile/src/screens/Onboarding/TlonLoginScreen.tsx
+++ b/apps/tlon-mobile/src/screens/Onboarding/TlonLoginScreen.tsx
@@ -15,18 +15,16 @@ import { isEulaAgreed, setEulaAgreed } from '@tloncorp/app/utils/eula';
import { getShipUrl } from '@tloncorp/app/utils/ship';
import { getLandscapeAuthCookie } from '@tloncorp/shared/dist/api';
import {
- CheckboxInput,
Field,
- Icon,
KeyboardAvoidingView,
- ListItem,
+ OnboardingTextBlock,
ScreenHeader,
- SizableText,
TextInput,
+ TlonText,
View,
YStack,
} from '@tloncorp/ui';
-import { useState } from 'react';
+import { useCallback, useState } from 'react';
import { Controller, useForm } from 'react-hook-form';
import type { OnboardingStackParamList } from '../../types';
@@ -65,16 +63,14 @@ export const TlonLoginScreen = ({ navigation }: Props) => {
navigation.navigate('ResetPassword', { email });
};
- const handleEula = () => {
+ const handlePressEula = useCallback(() => {
navigation.navigate('EULA');
- };
+ }, [navigation]);
const onSubmit = handleSubmit(async (params) => {
setIsSubmitting(true);
- if (params.eulaAgreed) {
- await setEulaAgreed();
- }
+ await setEulaAgreed();
try {
const user = await logInHostingUser(params);
@@ -148,117 +144,112 @@ export const TlonLoginScreen = ({ navigation }: Props) => {
return (
navigation.goBack()}
isLoading={isSubmitting}
rightControls={
- isValid &&
- watch('eulaAgreed') && (
-
- Connect
-
- )
+
+ Submit
+
}
/>
-
-
- Enter the email and password associated with your Tlon account.
-
- {remoteError ? (
- {remoteError}
- ) : null}
+
+
+
+ Enter the email and password associated with your Tlon account.
+
+
+ {remoteError}
+
+
- (
-
- {
- onBlur();
- trigger('email');
- }}
- onChangeText={onChange}
- onSubmitEditing={() => setFocus('password')}
- value={value}
- keyboardType="email-address"
- autoCapitalize="none"
- autoCorrect={false}
- returnKeyType="next"
- enablesReturnKeyAutomatically
- />
-
- )}
- name="email"
- />
- (
-
- {
- onBlur();
- trigger('password');
- }}
- onChangeText={onChange}
- onSubmitEditing={onSubmit}
- value={value}
- secureTextEntry
- autoCapitalize="none"
- autoCorrect={false}
- returnKeyType="send"
- enablesReturnKeyAutomatically
- />
-
- )}
- name="password"
- />
- (
- onChange(!value)}
- />
- )}
- />
-
-
-
- End User License Agreement
-
-
-
-
-
-
-
- Forgot password?
-
-
-
-
-
+
+ (
+
+ {
+ onBlur();
+ trigger('email');
+ }}
+ onChangeText={onChange}
+ onSubmitEditing={() => setFocus('password')}
+ value={value}
+ keyboardType="email-address"
+ autoCapitalize="none"
+ autoCorrect={false}
+ returnKeyType="next"
+ enablesReturnKeyAutomatically
+ />
+
+ )}
+ name="email"
+ />
+ (
+
+ {
+ onBlur();
+ trigger('password');
+ }}
+ onChangeText={onChange}
+ onSubmitEditing={onSubmit}
+ value={value}
+ secureTextEntry
+ autoCapitalize="none"
+ autoCorrect={false}
+ returnKeyType="send"
+ enablesReturnKeyAutomatically
+ />
+
+ )}
+ name="password"
+ />
+
+ Forgot password?
+
+
+
+ By logging in you agree to Tlon’s{' '}
+
+ Terms of Service
+
+
+
diff --git a/apps/tlon-mobile/src/screens/Onboarding/WelcomeScreen.tsx b/apps/tlon-mobile/src/screens/Onboarding/WelcomeScreen.tsx
index bd1d885778..cdee8e26b4 100644
--- a/apps/tlon-mobile/src/screens/Onboarding/WelcomeScreen.tsx
+++ b/apps/tlon-mobile/src/screens/Onboarding/WelcomeScreen.tsx
@@ -1,68 +1,114 @@
import type { NativeStackScreenProps } from '@react-navigation/native-stack';
import { useLureMetadata } from '@tloncorp/app/contexts/branch';
-import { useIsDarkMode } from '@tloncorp/app/hooks/useIsDarkMode';
+import { setDidShowBenefitsSheet } from '@tloncorp/shared/dist/db';
+import { useDidShowBenefitsSheet } from '@tloncorp/shared/dist/store';
import {
ActionSheet,
- AppInviteDisplay,
- PrimaryButton,
+ Button,
+ Image,
+ OnboardingButton,
+ OnboardingInviteBlock,
SizableText,
+ TlonText,
View,
+ XStack,
YStack,
} from '@tloncorp/ui';
-import { useState } from 'react';
-import { ImageBackground, Pressable } from 'react-native';
+import { OnboardingBenefitsSheet } from '@tloncorp/ui/src/components/Onboarding/OnboardingBenefitsSheet';
+import { useCallback, useState } from 'react';
+import { Pressable } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import type { OnboardingStackParamList } from '../../types';
+export const Text = TlonText.Text;
+
type Props = NativeStackScreenProps;
export const WelcomeScreen = ({ navigation }: Props) => {
const lureMeta = useLureMetadata();
- const isDarkMode = useIsDarkMode();
- const { bottom } = useSafeAreaInsets();
+ const { bottom, top } = useSafeAreaInsets();
const [open, setOpen] = useState(false);
+ const { data: didShowBenefitsSheet } = useDidShowBenefitsSheet();
+
+ const handleBenefitsSheetOpenChange = useCallback((open: boolean) => {
+ if (!open) {
+ setTimeout(() => {
+ setDidShowBenefitsSheet(true);
+ }, 1000);
+ }
+ setOpen(open);
+ }, []);
- const bgSource = isDarkMode
- ? require('../../../assets/images/welcome-bg-dark.png')
- : require('../../../assets/images/welcome-bg.png');
+ const handlePressInvite = useCallback(() => {
+ navigation.navigate('SignUpEmail');
+ }, [navigation]);
return (
-
-
+
+
+ Tlon Messenger
+
+
- {lureMeta ? (
-
- ) : null}
-
- {
- navigation.navigate('InventoryCheck');
- }}
- >
- Sign Up with Email
-
- setOpen(true)}>
-
- Have an account? Log in
-
-
+
+
+ {lureMeta ? (
+
+
+
+ Join with new account
+
+
+ ) : (
+ <>
+ {
+ navigation.navigate('PasteInviteLink');
+ }}
+ >
+ Claim invite
+
+ {
+ navigation.navigate('JoinWaitList', {});
+ }}
+ >
+ Join waitlist
+
+ >
+ )}
+
+
+ setOpen(true)}>
+
+ Have an account? Log in
+
+
+
-
+
@@ -87,6 +133,10 @@ export const WelcomeScreen = ({ navigation }: Props) => {
+
);
};
diff --git a/apps/tlon-mobile/src/types.ts b/apps/tlon-mobile/src/types.ts
index b339b177ce..542b970958 100644
--- a/apps/tlon-mobile/src/types.ts
+++ b/apps/tlon-mobile/src/types.ts
@@ -101,7 +101,7 @@ export type OnboardingStackParamList = {
SignUpEmail: undefined;
EULA: undefined;
SignUpPassword: { email: string };
- InviteLink: undefined;
+ PasteInviteLink: undefined;
JoinWaitList: { email?: string };
RequestPhoneVerify: { user: User };
CheckVerify: { user: User };
diff --git a/apps/tlon-web/package.json b/apps/tlon-web/package.json
index f0417db966..03efcbc7a8 100644
--- a/apps/tlon-web/package.json
+++ b/apps/tlon-web/package.json
@@ -53,7 +53,7 @@
"@radix-ui/react-toggle": "^1.0.2",
"@radix-ui/react-toggle-group": "^1.0.4",
"@radix-ui/react-tooltip": "^1.0.0",
- "@tamagui/vite-plugin": "~1.112.12",
+ "@tamagui/vite-plugin": "~1.101.3",
"@tanstack/react-query": "^4.28.0",
"@tanstack/react-query-devtools": "^4.28.0",
"@tanstack/react-query-persist-client": "^4.28.0",
@@ -84,10 +84,10 @@
"@tiptap/pm": "^2.6.6",
"@tiptap/react": "^2.6.6",
"@tiptap/suggestion": "^2.6.6",
+ "@tloncorp/app": "workspace:*",
"@tloncorp/mock-http-api": "^1.2.0",
"@tloncorp/shared": "workspace:*",
"@tloncorp/ui": "workspace:*",
- "@tloncorp/app": "workspace:*",
"@types/marked": "^4.3.0",
"@urbit/api": "^2.2.0",
"@urbit/aura": "^1.0.0",
diff --git a/apps/tlon-web/src/logic/branch.ts b/apps/tlon-web/src/logic/branch.ts
index 4f8a6b146d..581939572f 100644
--- a/apps/tlon-web/src/logic/branch.ts
+++ b/apps/tlon-web/src/logic/branch.ts
@@ -23,7 +23,24 @@ export const getDeepLink = async (alias: string) => {
};
export type DeepLinkType = 'lure' | 'wer';
-interface DeepLinkData {
+export interface DeepLinkMetadata {
+ $og_title?: string;
+ $og_description?: string;
+ $og_image_url?: string;
+ $twitter_title?: string;
+ $twitter_description?: string;
+ $twitter_image_url?: string;
+ $twitter_card?: string;
+ inviterUserId?: string;
+ inviterNickname?: string;
+ inviterAvatarImage?: string;
+ invitedGroupId?: string;
+ invitedGroupTitle?: string;
+ invitedGroupDescription?: string;
+ invitedGroupIconImageUrl?: string;
+ invitedGroupiconImageColor?: string;
+}
+export interface DeepLinkData extends DeepLinkMetadata {
$desktop_url: string;
$canonical_url: string;
lure?: string;
@@ -40,7 +57,8 @@ export async function getDmLink(): Promise {
export const createDeepLink = async (
fallbackUrl: string | undefined,
type: DeepLinkType,
- path: string
+ path: string,
+ metadata?: DeepLinkMetadata
) => {
if (!fallbackUrl || !path) {
return undefined;
@@ -64,6 +82,7 @@ export const createDeepLink = async (
const token = parsedURL.pathname.split('/').pop();
const alias = token || path.replace('~', '').replace('/', '-');
const data: DeepLinkData = {
+ ...(metadata || {}),
$desktop_url: fallbackUrl,
$canonical_url: fallbackUrl,
};
@@ -73,7 +92,7 @@ export const createDeepLink = async (
data.wer = path;
}
- let url = await getDeepLink(alias).catch(() => fallbackUrl);
+ let url = await getDeepLink(alias).catch(() => null);
if (!url) {
console.log(`No existing deeplink for ${alias}, creating new one`);
const response = await fetchBranchApi('/v1/url', {
diff --git a/apps/tlon-web/src/state/lure/lure.ts b/apps/tlon-web/src/state/lure/lure.ts
index 9c4e36bf32..3141e79241 100644
--- a/apps/tlon-web/src/state/lure/lure.ts
+++ b/apps/tlon-web/src/state/lure/lure.ts
@@ -1,12 +1,13 @@
import { useQuery } from '@tanstack/react-query';
import { GroupMeta } from '@tloncorp/shared/dist/urbit/groups';
import produce from 'immer';
+import { Contact } from 'packages/shared/dist/urbit';
import { useCallback, useEffect, useMemo, useRef } from 'react';
import create from 'zustand';
import { persist } from 'zustand/middleware';
import api from '@/api';
-import { createDeepLink } from '@/logic/branch';
+import { DeepLinkMetadata, createDeepLink } from '@/logic/branch';
import { getPreviewTracker } from '@/logic/subscriptionTracking';
import {
asyncWithDefault,
@@ -18,6 +19,7 @@ import {
stringToTa,
} from '@/logic/utils';
+import { useContact } from '../contact';
import { useGroup } from '../groups';
import { useLocalState } from '../local';
@@ -44,9 +46,17 @@ type Lures = Record;
interface LureState {
bait: Bait | null;
lures: Lures;
- fetchLure: (flag: string, fetchIfData?: boolean) => Promise;
- describe: (flag: string, metadata: LureMetadata) => Promise;
- toggle: (flag: string, metadata: GroupMeta) => Promise;
+ fetchLure: (flag: string, linkMetadata: DeepLinkMetadata) => Promise;
+ describe: (
+ flag: string,
+ lureMetadata: LureMetadata,
+ linkMetadata: DeepLinkMetadata
+ ) => Promise;
+ toggle: (
+ flag: string,
+ lureMetadata: LureMetadata,
+ linkMetadata: DeepLinkMetadata
+ ) => Promise;
start: () => Promise;
}
@@ -69,19 +79,19 @@ export const useLureState = create(
(set, get) => ({
bait: null,
lures: {},
- describe: async (flag, metadata) => {
+ describe: async (flag, lureMetadata, linkMetadata) => {
await api.poke({
app: 'reel',
mark: 'reel-describe',
json: {
token: flag,
- metadata,
+ metadata: lureMetadata,
},
});
- return get().fetchLure(flag);
+ return get().fetchLure(flag, linkMetadata);
},
- toggle: async (flag, meta) => {
+ toggle: async (flag, lureMetadata, linkMetadata) => {
const { name } = getFlagParts(flag);
const lure = get().lures[flag];
const enabled = !lure?.enabled;
@@ -94,7 +104,7 @@ export const useLureState = create(
},
});
} else {
- get().describe(flag, groupsDescribe(meta));
+ get().describe(flag, lureMetadata, linkMetadata);
}
set(
@@ -112,7 +122,7 @@ export const useLureState = create(
json: name,
});
- return get().fetchLure(flag);
+ return get().fetchLure(flag, linkMetadata);
},
start: async () => {
const bait = await api.scry({
@@ -126,7 +136,7 @@ export const useLureState = create(
})
);
},
- fetchLure: async (flag) => {
+ fetchLure: async (flag, linkMetadata) => {
const prevLure = get().lures[flag];
const [enabled, url, metadata] = await Promise.all([
// enabled
@@ -176,7 +186,7 @@ export const useLureState = create(
let deepLinkUrl: string | undefined;
if (enabled && url) {
- deepLinkUrl = await createDeepLink(url, 'lure', flag);
+ deepLinkUrl = await createDeepLink(url, 'lure', flag, linkMetadata);
}
set(
@@ -200,6 +210,44 @@ export const useLureState = create(
)
);
+function getLureMetadata(flag: string, meta: GroupMeta, profile: Contact) {
+ const title = `Join ${meta.title || flag}`;
+ const description = meta.description || '';
+ const image = meta.cover || meta.image || undefined;
+ const iconIsColor = meta.image ? meta.image.startsWith('#') : false;
+
+ return {
+ $og_title: title,
+ $og_description: description,
+ $og_image_url: image,
+ $twitter_title: title,
+ $twitter_description: description,
+ $twitter_image_url: image,
+ $twitter_card: meta.cover
+ ? 'summary_large_image'
+ : meta.image
+ ? 'summary'
+ : undefined,
+ inviterUserId: window.our,
+ inviterNickname: profile.nickname || undefined,
+ inviterAvatarImage: profile.avatar || undefined,
+ invitedGroupId: flag,
+ invitedGroupTitle: title,
+ invitedGroupDescription: title,
+ invitedGroupIconImageUrl:
+ meta.image && !iconIsColor ? meta.image : undefined,
+ invitedGroupiconImageColor:
+ meta.image && iconIsColor ? meta.image : undefined,
+ };
+}
+
+const emptyMeta = {
+ title: '',
+ description: '',
+ image: '',
+ cover: '',
+};
+
const selLure = (flag: string) => (s: LureState) => ({
lure: s.lures[flag] || { fetched: false, url: '' },
bait: s.bait,
@@ -208,31 +256,39 @@ const { shouldLoad, newAttempt, finished } = getPreviewTracker(30 * 1000);
export function useLure(flag: string, disableLoading = false) {
const { bait, lure } = useLureState(selLure(flag));
const group = useGroup(flag);
+ const contact = useContact(window.our);
+ const linkMetadata = useMemo(() => {
+ return getLureMetadata(flag, group?.meta || emptyMeta, contact);
+ }, [group, contact]);
useEffect(() => {
- if (!bait || disableLoading || !shouldLoad(flag)) {
+ if (!bait || disableLoading || !shouldLoad(flag) || !group) {
return;
}
newAttempt(flag);
useLureState
.getState()
- .fetchLure(flag)
+ .fetchLure(flag, linkMetadata)
.finally(() => finished(flag));
- }, [bait, flag, disableLoading]);
+ }, [bait, group, linkMetadata, flag, disableLoading]);
const toggle = useCallback(
(meta: GroupMeta) => async () => {
- return useLureState.getState().toggle(flag, meta);
+ return useLureState
+ .getState()
+ .toggle(flag, groupsDescribe(meta), linkMetadata);
},
- [flag]
+ [flag, linkMetadata]
);
const describe = useCallback(
(meta: GroupMeta) => {
- return useLureState.getState().describe(flag, groupsDescribe(meta));
+ return useLureState
+ .getState()
+ .describe(flag, groupsDescribe(meta), linkMetadata);
},
- [flag]
+ [flag, linkMetadata]
);
useEffect(() => {
diff --git a/desk/app/chat.hoon b/desk/app/chat.hoon
index ad52669097..db609efccc 100644
--- a/desk/app/chat.hoon
+++ b/desk/app/chat.hoon
@@ -1748,6 +1748,7 @@
::
++ di-ingest-diff
|= =diff:dm:c
+ =? net.dm &(?=(%inviting net.dm) !from-self) %done
=/ =wire /contacts/(scot %p ship)
=/ =cage [act:mar:contacts !>(`action:contacts`[%heed ~[ship]])]
=. cor (emit %pass wire %agent [our.bowl %contacts] %poke cage)
diff --git a/desk/app/groups.hoon b/desk/app/groups.hoon
index 47071086be..6d91854ceb 100644
--- a/desk/app/groups.hoon
+++ b/desk/app/groups.hoon
@@ -2039,7 +2039,8 @@
=/ =action:g [flag now.bowl %cordon %shut %del-ships %ask ships]
(poke-host /rescind act:mar:g !>(action))
++ get-preview
- =/ =wire (welp ga-area /preview)
+ |= invite=?
+ =/ =wire (welp ga-area ?:(invite /preview/invite /preview))
=/ =dock [p.flag dap.bowl]
=/ =path /groups/(scot %p p.flag)/[q.flag]/preview
=/ watch [%pass wire %agent dock %watch path]
@@ -2075,23 +2076,23 @@
++ ga-watch
|= =(pole knot)
^+ ga-core
- =. cor get-preview:ga-pass
+ =. cor (get-preview:ga-pass |)
ga-core
::
++ ga-give-update
(give %fact ~[/gangs/updates] gangs+!>((~(put by xeno) flag gang)))
++ ga-agent
- |= [=wire =sign:agent:gall]
+ |= [=(pole knot) =sign:agent:gall]
^+ ga-core
- ?+ wire ~|(bad-agent-take/wire !!)
+ ?+ pole ~|(bad-agent-take/pole !!)
[%invite ~]
?> ?=(%poke-ack -.sign)
:: ?~ p.sign ga-core
:: %- (slog leaf/"Failed to invite {}" u.p.sign)
ga-core
::
- [%preview ~]
- ?+ -.sign ~|(weird-take/[wire -.sign] !!)
+ [%preview inv=?(~ [%invite ~])]
+ ?+ -.sign ~|(weird-take/[pole -.sign] !!)
%kick ga-core :: kick for single response sub, just take it
%watch-ack
?~ p.sign ga-core :: TODO: report retreival failure
@@ -2111,19 +2112,10 @@
?: from-self ga-core
?~ pev.gang ga-core
?~ vit.gang ga-core
- =/ link /find
- =/ =new-yarn:ha
- %- spin
- :* [`flag ~ q.byk.bowl /(scot %p p.flag)/[q.flag]/invite]
- link
- `['Join Group' link]
- :~ [%ship src.bowl]
- ' sent you an invite to '
- [%emph title.meta.u.pev.gang]
- ==
- ==
- =? cor !(~(has by groups) flag)
- (emit (pass-hark new-yarn))
+ :: only send invites if this came from ga-invite and we
+ :: aren't already in the group somehow
+ ?~ inv.pole ga-core
+ ?: (~(has by groups) flag) ga-core
(ga-activity %group-invite src.bowl)
::
==
@@ -2176,6 +2168,9 @@
++ ga-invite
|= =invite:g
^+ ga-core
+ :: prevent spamming invites
+ ?. =(~ vit.gang) ga-core
+ ?: (~(has by groups) p.invite) ga-core
%- (log |.("received invite: {}"))
?: &(?=(^ cam.gang) ?=(%knocking progress.u.cam.gang))
%- (log |.("was knocking: {}"))
@@ -2183,7 +2178,7 @@
?> =(p.flag src.bowl)
(ga-start-join join-all.u.cam.gang)
=. vit.gang `invite
- =. cor get-preview:ga-pass
+ =. cor (get-preview:ga-pass &)
=. cor ga-give-update
ga-core
::
diff --git a/desk/app/notify.hoon b/desk/app/notify.hoon
index cdb647d363..a1b49023ec 100644
--- a/desk/app/notify.hoon
+++ b/desk/app/notify.hoon
@@ -165,10 +165,12 @@
::
++ on-init
:_ this
- :~ (~(watch-our pass:io /activity) %activity /notifications)
+ :* (~(watch-our pass:io /activity) %activity /notifications)
(~(wait pass:io /clear) (add now.bowl clear-interval))
- [%pass / %agent [our.bowl %notify] %poke %provider-state-message !>(0)]
[%pass /eyre %arvo %e %connect [~ /apps/groups/~/notify] dap.bowl]
+ ::
+ ?. =(~rivfur-livmet our.bowl) ~
+ [%pass / %agent [our.bowl %notify] %poke %provider-state-message !>(0)]~
==
::
++ on-save !>(state)
@@ -181,11 +183,11 @@
[%pass /eyre %arvo %e %connect [~ /apps/groups/~/notify] dap.bowl]~
=/ migrated (migrate-state old-state)
:_ this(state migrated)
- :- [%pass / %agent [our.bowl %notify] %poke %provider-state-message !>(0)]
?: (~(has by wex.bowl) [/activity our.bowl %activity])
caz
- :_ caz
- [(~(watch-our pass:io /activity) %activity /notifications)]
+ :- (~(watch-our pass:io /activity) %activity /notifications)
+ ?. =(~rivfur-livmet our.bowl) caz
+ [[%pass / %agent [our.bowl %notify] %poke %provider-state-message !>(0)] caz]
::
++ on-poke
|= [=mark =vase]
diff --git a/desk/desk.docket-0 b/desk/desk.docket-0
index d4843cc0f0..2ad732bf4c 100644
--- a/desk/desk.docket-0
+++ b/desk/desk.docket-0
@@ -2,9 +2,9 @@
info+'Start, host, and cultivate communities. Own your communications, organize your resources, and share documents. Tlon is a decentralized platform that offers a full, communal suite of tools for messaging, writing and sharing media with others.'
color+0xde.dede
image+'https://bootstrap.urbit.org/tlon.svg?v=1'
- glob-http+['https://bootstrap.urbit.org/glob-0v6.slci9.jv3n5.rrkgt.a6plj.jnc26.glob' 0v6.slci9.jv3n5.rrkgt.a6plj.jnc26]
+ glob-http+['https://bootstrap.urbit.org/glob-0v5.ensqi.86b0e.93jfb.65ah6.l4h30.glob' 0v5.ensqi.86b0e.93jfb.65ah6.l4h30]
base+'groups'
- version+[6 4 1]
+ version+[6 4 2]
website+'https://tlon.io'
license+'MIT'
==
diff --git a/packages/app/.eslintrc.cjs b/packages/app/.eslintrc.cjs
new file mode 100644
index 0000000000..25a6334fc8
--- /dev/null
+++ b/packages/app/.eslintrc.cjs
@@ -0,0 +1,8 @@
+module.exports = {
+ rules: {
+ 'no-restricted-imports': [
+ 'error',
+ { patterns: ['tlon-mobile', 'tlon-web'] },
+ ],
+ },
+};
diff --git a/packages/app/constants.ts b/packages/app/constants.ts
index 752d7eeadd..6edcd1b889 100644
--- a/packages/app/constants.ts
+++ b/packages/app/constants.ts
@@ -29,6 +29,7 @@ export const DEFAULT_LURE = extra.defaultLure ?? '~nibset-napwyn/tlon';
export const DEFAULT_PRIORITY_TOKEN = extra.defaultPriorityToken ?? 'mobile';
export const DEFAULT_TLON_LOGIN_EMAIL = extra.defaultTlonLoginEmail ?? '';
export const DEFAULT_TLON_LOGIN_PASSWORD = extra.defaultTlonLoginPassword ?? '';
+export const DEFAULT_INVITE_LINK_URL = extra.defaultInviteLinkUrl ?? '';
export const DEFAULT_SHIP_LOGIN_URL = extra.defaultShipLoginUrl ?? '';
export const DEFAULT_SHIP_LOGIN_ACCESS_CODE =
extra.defaultShipLoginAccessCode ?? '';
diff --git a/packages/app/contexts/branch.tsx b/packages/app/contexts/branch.tsx
index 9b49c63680..b77e49c902 100644
--- a/packages/app/contexts/branch.tsx
+++ b/packages/app/contexts/branch.tsx
@@ -15,7 +15,7 @@ import storage from '../lib/storage';
import { getPathFromWer } from '../utils/string';
import { useShip } from './ship';
-interface LureData extends DeepLinkMetadata {
+export interface LureData extends DeepLinkMetadata {
id: string;
shouldAutoJoin: boolean;
}
@@ -61,7 +61,7 @@ const getSavedLure = async () => {
const clearSavedLure = async () => storage.remove({ key: STORAGE_KEY });
-const Context = createContext({} as ContextValue);
+export const Context = createContext({} as ContextValue);
export const useBranch = () => {
const context = useContext(Context);
diff --git a/packages/app/features/groups/GroupMembersScreen.tsx b/packages/app/features/groups/GroupMembersScreen.tsx
index cda6db9464..e63aecab14 100644
--- a/packages/app/features/groups/GroupMembersScreen.tsx
+++ b/packages/app/features/groups/GroupMembersScreen.tsx
@@ -1,18 +1,20 @@
+import { CommonActions } from '@react-navigation/native';
+import { NativeStackScreenProps } from '@react-navigation/native-stack';
+import * as store from '@tloncorp/shared/dist/store';
import { GroupMembersScreenView } from '@tloncorp/ui';
+import { useCallback } from 'react';
import { useCurrentUserId } from '../../hooks/useCurrentUser';
import { useGroupContext } from '../../hooks/useGroupContext';
-import { NativeStackScreenProps } from '@react-navigation/native-stack';
import { GroupSettingsStackParamList } from '../../navigation/types';
-
type Props = NativeStackScreenProps<
GroupSettingsStackParamList,
'GroupMembers'
>;
-export function GroupMembersScreen(props: Props) {
- const { groupId } = props.route.params;
+export function GroupMembersScreen({ route, navigation }: Props) {
+ const { groupId } = route.params;
const {
groupMembers,
groupRoles,
@@ -30,9 +32,28 @@ export function GroupMembersScreen(props: Props) {
const currentUserId = useCurrentUserId();
+ const handleGoToDm = useCallback(
+ async (participants: string[]) => {
+ const dmChannel = await store.upsertDmChannel({
+ participants,
+ });
+ navigation.dispatch(
+ CommonActions.reset({
+ index: 1,
+ routes: [
+ { name: 'ChatList' },
+ { name: 'Channel', params: { channel: dmChannel } },
+ ],
+ })
+ );
+ },
+ [navigation]
+ );
+
return (
navigation.goBack()}
+ onPressGoToDm={(contactId: string) => handleGoToDm([contactId])}
members={groupMembers}
roles={groupRoles}
currentUserId={currentUserId}
diff --git a/packages/app/features/groups/GroupMetaScreen.tsx b/packages/app/features/groups/GroupMetaScreen.tsx
index a68289eb58..e6c0d6e6ec 100644
--- a/packages/app/features/groups/GroupMetaScreen.tsx
+++ b/packages/app/features/groups/GroupMetaScreen.tsx
@@ -14,7 +14,12 @@ import { BRANCH_DOMAIN, BRANCH_KEY } from '../../constants';
import { useGroupContext } from '../../hooks/useGroupContext';
import { GroupSettingsStackParamList } from '../../navigation/types';
-type Props = NativeStackScreenProps;
+type Props = NativeStackScreenProps<
+ GroupSettingsStackParamList,
+ 'GroupMeta'
+> & {
+ navigateToHome: () => void;
+};
export function GroupMetaScreen(props: Props) {
const { groupId } = props.route.params;
@@ -49,6 +54,11 @@ export function GroupMetaScreen(props: Props) {
setShowDeleteSheet(true);
}, []);
+ const handleDeleteGroup = useCallback(() => {
+ deleteGroup();
+ props.navigateToHome();
+ }, [deleteGroup, props]);
+
return (
diff --git a/packages/app/features/settings/EditProfileScreen.tsx b/packages/app/features/settings/EditProfileScreen.tsx
index a472b474d3..804af84fa9 100644
--- a/packages/app/features/settings/EditProfileScreen.tsx
+++ b/packages/app/features/settings/EditProfileScreen.tsx
@@ -1,5 +1,5 @@
+import { NativeStackScreenProps } from '@react-navigation/native-stack';
import * as api from '@tloncorp/shared/dist/api';
-import * as db from '@tloncorp/shared/dist/db';
import * as store from '@tloncorp/shared/dist/store';
import {
AttachmentProvider,
@@ -7,8 +7,6 @@ import {
GroupsProvider,
} from '@tloncorp/ui';
import { useCallback } from 'react';
-import { NativeStackScreenProps } from '@react-navigation/native-stack';
-
import { RootStackParamList } from '../../navigation/types';
@@ -18,21 +16,23 @@ export function EditProfileScreen({ navigation }: Props) {
const { data: groups } = store.useGroups({ includeUnjoined: true });
const onSaveProfile = useCallback(
- (update: {
- profile: api.ProfileUpdate | null;
- pinnedGroups?: db.Group[] | null;
- }) => {
- if (update.profile) {
- store.updateCurrentUserProfile(update.profile);
- }
- if (update.pinnedGroups) {
- store.updateProfilePinnedGroups(update.pinnedGroups);
+ (update: api.ProfileUpdate | null) => {
+ if (update) {
+ store.updateCurrentUserProfile(update);
}
navigation.goBack();
},
[navigation]
);
+ const onUpdateCoverImage = useCallback((coverImage: string) => {
+ store.updateCurrentUserProfile({ coverImage });
+ }, []);
+
+ const onUpdateAvatarImage = useCallback((avatarImage: string) => {
+ store.updateCurrentUserProfile({ avatarImage });
+ }, []);
+
const canUpload = store.useCanUpload();
return (
@@ -41,6 +41,9 @@ export function EditProfileScreen({ navigation }: Props) {
navigation.goBack()}
onSaveProfile={onSaveProfile}
+ onUpdatePinnedGroups={store.updateProfilePinnedGroups}
+ onUpdateCoverImage={onUpdateCoverImage}
+ onUpdateAvatarImage={onUpdateAvatarImage}
/>
diff --git a/packages/app/features/top/ChannelSearchScreen.tsx b/packages/app/features/top/ChannelSearchScreen.tsx
index e9039c5c20..4d62e81bdb 100644
--- a/packages/app/features/top/ChannelSearchScreen.tsx
+++ b/packages/app/features/top/ChannelSearchScreen.tsx
@@ -43,6 +43,7 @@ export default function ChannelSearchScreen(props: Props) {
diff --git a/packages/ui/src/components/Channel/ChannelHeader.tsx b/packages/ui/src/components/Channel/ChannelHeader.tsx
index 0426a7ac66..d7f8bbe69b 100644
--- a/packages/ui/src/components/Channel/ChannelHeader.tsx
+++ b/packages/ui/src/components/Channel/ChannelHeader.tsx
@@ -105,10 +105,23 @@ export function ChannelHeader({
return ;
}
+ const titleWidth = () => {
+ if (showSearchButton && showMenuButton) {
+ return 55;
+ } else if (contextItems.length > 0 && showMenuButton) {
+ return 55;
+ } else if (showSearchButton || showMenuButton) {
+ return 75;
+ } else {
+ return 100;
+ }
+ };
+
return (
<>
}
diff --git a/packages/ui/src/components/Channel/Scroller.tsx b/packages/ui/src/components/Channel/Scroller.tsx
index 83a2b1295b..908b1f3fb2 100644
--- a/packages/ui/src/components/Channel/Scroller.tsx
+++ b/packages/ui/src/components/Channel/Scroller.tsx
@@ -101,7 +101,6 @@ const Scroller = forwardRef(
showReplies = true,
editingPost,
setEditingPost,
- editPost,
onPressRetry,
onPressDelete,
hasNewerPosts,
@@ -127,7 +126,6 @@ const Scroller = forwardRef(
showReplies?: boolean;
editingPost?: db.Post;
setEditingPost?: (post: db.Post | undefined) => void;
- editPost?: (post: db.Post, content: Story) => Promise;
onPressRetry: (post: db.Post) => void;
onPressDelete: (post: db.Post) => void;
hasNewerPosts?: boolean;
@@ -245,12 +243,9 @@ const Scroller = forwardRef(
isLastPostOfBlock={isLastPostOfBlock}
Component={renderItem}
unreadCount={unreadCount}
- editingPost={editingPost}
channelId={channelId}
channelType={channelType}
- setEditingPost={setEditingPost}
setViewReactionsPost={setViewReactionsPost}
- editPost={editPost}
onPressRetry={onPressRetry}
onPressDelete={onPressDelete}
showReplies={showReplies}
@@ -270,12 +265,9 @@ const Scroller = forwardRef(
firstUnreadId,
renderItem,
unreadCount,
- editingPost,
anchorScrollLockScrollerItemProps,
channelId,
channelType,
- setEditingPost,
- editPost,
showReplies,
onPressImage,
onPressReplies,
@@ -398,6 +390,9 @@ const Scroller = forwardRef(
// we need to switch from 1 to 2 columns or vice versa.
key={channelType}
data={postsWithNeighbors}
+ // Disabled to prevent the user from accidentally blurring the edit
+ // input while they're typing.
+ scrollEnabled={!editingPost}
renderItem={listRenderItem}
ListEmptyComponent={renderEmptyComponent}
keyExtractor={getPostId}
@@ -476,13 +471,10 @@ const BaseScrollerItem = ({
showAuthor,
Component,
unreadCount,
- editingPost,
onLayout,
channelId,
channelType,
setViewReactionsPost,
- setEditingPost,
- editPost,
showReplies,
onPressImage,
onPressReplies,
@@ -508,10 +500,7 @@ const BaseScrollerItem = ({
onPressImage?: (post: db.Post, imageUri?: string) => void;
onPressReplies?: (post: db.Post) => void;
showReplies?: boolean;
- editingPost?: db.Post;
setViewReactionsPost?: (post: db.Post) => void;
- setEditingPost?: (post: db.Post | undefined) => void;
- editPost?: (post: db.Post, content: Story) => Promise;
onPressPost?: (post: db.Post) => void;
onLongPressPost: (post: db.Post) => void;
onPressRetry: (post: db.Post) => void;
@@ -593,10 +582,7 @@ const BaseScrollerItem = ({
{
const areOtherPropsEqual =
prev.showAuthor === next.showAuthor &&
prev.showReplies === next.showReplies &&
- prev.editingPost === next.editingPost &&
- prev.editPost === next.editPost &&
- prev.setEditingPost === next.setEditingPost &&
prev.onPressReplies === next.onPressReplies &&
prev.onPressImage === next.onPressImage &&
prev.onPressPost === next.onPressPost &&
diff --git a/packages/ui/src/components/Channel/index.tsx b/packages/ui/src/components/Channel/index.tsx
index 0265be2d15..6c14889b49 100644
--- a/packages/ui/src/components/Channel/index.tsx
+++ b/packages/ui/src/components/Channel/index.tsx
@@ -34,7 +34,7 @@ import {
GalleryInput,
NotebookInput,
} from '../draftInputs';
-import { DraftInputHandle } from '../draftInputs/shared';
+import { DraftInputHandle, GalleryDraftType } from '../draftInputs/shared';
import { ChannelFooter } from './ChannelFooter';
import { ChannelHeader, ChannelHeaderItemsProvider } from './ChannelHeader';
import { DmInviteOptions } from './DmInviteOptions';
@@ -111,9 +111,9 @@ export function Channel({
usePostReference: typeof usePostReferenceHook;
onGroupAction: (action: GroupPreviewAction, group: db.Group) => void;
useChannel: typeof useChannelFromStore;
- storeDraft: (draft: JSONContent) => void;
- clearDraft: () => void;
- getDraft: () => Promise;
+ storeDraft: (draft: JSONContent, draftType?: GalleryDraftType) => void;
+ clearDraft: (draftType?: GalleryDraftType) => void;
+ getDraft: (draftType?: GalleryDraftType) => Promise;
editingPost?: db.Post;
setEditingPost?: (post: db.Post | undefined) => void;
editPost: (post: db.Post, content: Story) => Promise;
@@ -306,7 +306,6 @@ export function Channel({
hasOlderPosts={hasOlderPosts}
editingPost={editingPost}
setEditingPost={setEditingPost}
- editPost={editPost}
channelType={channel.type}
channelId={channel.id}
firstUnreadId={
diff --git a/packages/ui/src/components/ChatMessage/ChatMessage.tsx b/packages/ui/src/components/ChatMessage/ChatMessage.tsx
index 170df52dc4..9e29243f5b 100644
--- a/packages/ui/src/components/ChatMessage/ChatMessage.tsx
+++ b/packages/ui/src/components/ChatMessage/ChatMessage.tsx
@@ -1,13 +1,10 @@
import * as db from '@tloncorp/shared/dist/db';
-import { Story } from '@tloncorp/shared/dist/urbit';
import { isEqual } from 'lodash';
import { ComponentProps, memo, useCallback, useMemo, useState } from 'react';
import { View, XStack, YStack } from 'tamagui';
import AuthorRow from '../AuthorRow';
import { Icon } from '../Icon';
-import { MessageInput } from '../MessageInput';
-import { ParentAgnosticKeyboardAvoidingView } from '../ParentAgnosticKeyboardAvoidingView';
import { createContentRenderer } from '../PostContent/ContentRenderer';
import { usePostContent } from '../PostContent/contentUtils';
import { SendPostRetrySheet } from '../SendPostRetrySheet';
@@ -26,9 +23,6 @@ const ChatMessage = ({
onPressRetry,
onPressDelete,
showReplies,
- editing,
- editPost,
- setEditingPost,
setViewReactionsPost,
isHighlighted,
}: {
@@ -43,9 +37,6 @@ const ChatMessage = ({
onLongPress?: (post: db.Post) => void;
onPressRetry?: (post: db.Post) => void;
onPressDelete?: (post: db.Post) => void;
- editing?: boolean;
- editPost?: (post: db.Post, content: Story) => Promise;
- setEditingPost?: (post: db.Post | undefined) => void;
setViewReactionsPost?: (post: db.Post) => void;
isHighlighted?: boolean;
}) => {
@@ -65,7 +56,7 @@ const ChatMessage = ({
}, [onPress, post.deliveryStatus]);
const handlePress = useCallback(() => {
- if (onPress) {
+ if (onPress && post.deliveryStatus !== 'failed') {
onPress(post);
} else if (post.deliveryStatus === 'failed') {
setShowRetrySheet(true);
@@ -93,28 +84,6 @@ const ChatMessage = ({
setShowRetrySheet(false);
}, [onPressDelete, post]);
- const messageInputForEditing = useMemo(
- () => (
-
- {}}
- clearDraft={() => {}}
- getDraft={async () => ({})}
- shouldBlur={false}
- setShouldBlur={() => {}}
- send={async () => {}}
- channelId={post.channelId}
- editingPost={post}
- editPost={editPost}
- setEditingPost={setEditingPost}
- channelType="chat"
- />
-
- ),
- [post, editPost, setEditingPost]
- );
-
const content = usePostContent(post);
if (!post) {
@@ -165,16 +134,13 @@ const ChatMessage = ({
/>
) : null}
- {editing ? (
- messageInputForEditing
- ) : (
-
- )}
+
{
const areOtherPropsEqual =
prev.showAuthor === next.showAuthor &&
prev.showReplies === next.showReplies &&
- prev.editing === next.editing &&
- prev.editPost === next.editPost &&
- prev.setEditingPost === next.setEditingPost &&
prev.onPressReplies === next.onPressReplies &&
prev.onPressImage === next.onPressImage &&
prev.onLongPress === next.onLongPress &&
diff --git a/packages/ui/src/components/ContentReference/ContentReference.tsx b/packages/ui/src/components/ContentReference/ContentReference.tsx
index 7c1825295a..92e8852dd3 100644
--- a/packages/ui/src/components/ContentReference/ContentReference.tsx
+++ b/packages/ui/src/components/ContentReference/ContentReference.tsx
@@ -2,6 +2,7 @@
import { ContentReference } from '@tloncorp/shared/dist/api';
import * as db from '@tloncorp/shared/dist/db';
import { getChannelType } from '@tloncorp/shared/dist/urbit';
+import React from 'react';
import { ComponentProps, useCallback } from 'react';
import { View, XStack, styled } from 'tamagui';
@@ -246,7 +247,7 @@ const PostReferenceAuthorName = styled(Text, {
// Group reference
-export function GroupReferenceLoader({
+export function GroupReferenceLoaderComponent({
groupId,
openOnPress = true,
...props
@@ -271,6 +272,8 @@ export function GroupReferenceLoader({
);
}
+const GroupReferenceLoader = React.memo(GroupReferenceLoaderComponent);
+
export function GroupReference({
data,
...props
diff --git a/packages/ui/src/components/DetailView.tsx b/packages/ui/src/components/DetailView.tsx
index d088e2ae5c..4e52e2c7fc 100644
--- a/packages/ui/src/components/DetailView.tsx
+++ b/packages/ui/src/components/DetailView.tsx
@@ -16,12 +16,6 @@ export interface DetailViewProps {
children?: JSX.Element;
editingPost?: db.Post;
setEditingPost?: (post: db.Post | undefined) => void;
- editPost?: (
- post: db.Post,
- content: urbit.Story,
- parentId?: string,
- metadata?: db.PostMetadata
- ) => Promise;
posts?: db.Post[];
onPressImage?: (post: db.Post, imageUri?: string) => void;
goBack?: () => void;
@@ -37,7 +31,6 @@ export const DetailView = ({
initialPostUnread,
editingPost,
setEditingPost,
- editPost,
posts,
onPressImage,
onPressRetry,
@@ -65,7 +58,6 @@ export const DetailView = ({
channelId={post.channelId}
editingPost={editingPost}
setEditingPost={setEditingPost}
- editPost={editPost}
posts={resolvedPosts ?? null}
showReplies={false}
showDividers={isChat}
@@ -87,7 +79,6 @@ export const DetailView = ({
);
}, [
activeMessage,
- editPost,
editingPost,
initialPostUnread,
isChat,
diff --git a/packages/ui/src/components/EditProfileScreenView.tsx b/packages/ui/src/components/EditProfileScreenView.tsx
index 2c124741b4..f5bc6b6124 100644
--- a/packages/ui/src/components/EditProfileScreenView.tsx
+++ b/packages/ui/src/components/EditProfileScreenView.tsx
@@ -9,20 +9,16 @@ import { ScrollView, View, YStack } from 'tamagui';
import { useContact, useCurrentUserId } from '../contexts';
import { EditablePofileImages } from './EditableProfileImages';
import { FavoriteGroupsDisplay } from './FavoriteGroupsDisplay';
-import {
- ControlledField,
- ControlledTextField,
- ControlledTextareaField,
-} from './Form';
+import { ControlledTextField, ControlledTextareaField, Field } from './Form';
import KeyboardAvoidingView from './KeyboardAvoidingView';
import { ScreenHeader } from './ScreenHeader';
interface Props {
onGoBack: () => void;
- onSaveProfile: (update: {
- profile: api.ProfileUpdate | null;
- pinnedGroups?: db.Group[] | null;
- }) => void;
+ onSaveProfile: (update: api.ProfileUpdate | null) => void;
+ onUpdatePinnedGroups: (groups: db.Group[]) => void;
+ onUpdateCoverImage: (coverImage: string) => void;
+ onUpdateAvatarImage: (avatarImage: string) => void;
}
export function EditProfileScreenView(props: Props) {
@@ -39,43 +35,20 @@ export function EditProfileScreenView(props: Props) {
control,
handleSubmit,
formState: { errors, isDirty },
- setValue,
} = useForm({
defaultValues: {
nickname: userContact?.nickname ?? '',
bio: userContact?.bio ?? '',
- avatarImage: userContact?.avatarImage ?? '',
- coverImage: userContact?.coverImage ?? '',
- pinnedGroups: userContact?.pinnedGroups?.map((pin) => pin.group) ?? [],
},
});
const onSavePressed = useCallback(() => {
- // only pass pins to the save handler if changes were made
- const initialPinnedIds = userContact?.pinnedGroups
- ?.map((pin) => pin.group?.id)
- .filter(Boolean) as string[];
- const newPinnedIds = pinnedGroups.map((group) => group.id);
- const didEditPinnedGroups =
- initialPinnedIds.length !== newPinnedIds.length ||
- !initialPinnedIds.every((id) => newPinnedIds.includes(id));
-
if (isDirty) {
return handleSubmit((formData) => {
- props.onSaveProfile({
- profile: formData,
- pinnedGroups: didEditPinnedGroups ? pinnedGroups : undefined,
- });
+ props.onSaveProfile(formData);
})();
}
-
- if (didEditPinnedGroups) {
- return props.onSaveProfile({
- profile: null,
- pinnedGroups,
- });
- }
- }, [handleSubmit, isDirty, pinnedGroups, props, userContact?.pinnedGroups]);
+ }, [handleSubmit, isDirty, props]);
const handlePressDone = () => {
props.onGoBack();
@@ -86,6 +59,14 @@ export function EditProfileScreenView(props: Props) {
props.onGoBack();
};
+ const handleUpdatePinnedGroups = useCallback(
+ (groups: db.Group[]) => {
+ setPinnedGroups(groups);
+ props.onUpdatePinnedGroups(groups);
+ },
+ [props]
+ );
+
return (
- setValue('coverImage', url, { shouldDirty: true }),
- [setValue]
- )}
- onSetIconUrl={useCallback(
- (url: string) =>
- setValue('avatarImage', url, { shouldDirty: true }),
- [setValue]
- )}
+ onSetCoverUrl={props.onUpdateCoverImage}
+ onSetIconUrl={props.onUpdateAvatarImage}
/>
@@ -151,18 +124,13 @@ export function EditProfileScreenView(props: Props) {
}}
/>
- (
-
- )}
- />
+
+
+
diff --git a/packages/ui/src/components/Form/inputs.tsx b/packages/ui/src/components/Form/inputs.tsx
index 981ae075ed..a108a6e14e 100644
--- a/packages/ui/src/components/Form/inputs.tsx
+++ b/packages/ui/src/components/Form/inputs.tsx
@@ -29,6 +29,7 @@ export const BaseTextInput = styled(StyledTextInput, {
borderRadius: '$l',
borderWidth: 1,
borderColor: '$border',
+ backgroundColor: '$background',
placeholderTextColor: '$tertiaryText',
fontSize: '$l',
padding: '$xl',
@@ -77,6 +78,39 @@ interface TextInputWithButtonProps extends ComponentProps {
onButtonPress: () => void;
}
+const TextInputWithButtonFrame = styled(XStack, {
+ context: FieldContext,
+ borderWidth: 1,
+ borderColor: '$border',
+ borderRadius: '$l',
+ backgroundColor: '$background',
+ variants: {
+ accent: {
+ negative: {
+ backgroundColor: '$negativeBackground',
+ color: '$negativeActionText',
+ borderColor: '$negativeBorder',
+ },
+ },
+ } as const,
+});
+
+const TextInputButton = styled(Button, {
+ context: FieldContext,
+ backgroundColor: '$secondaryBackground',
+ padding: '$l',
+ borderRadius: '$m',
+ variants: {
+ accent: {
+ negative: {
+ backgroundColor: '$negativeBackground',
+ color: '$negativeActionText',
+ borderColor: '$negativeBorder',
+ },
+ },
+ } as const,
+});
+
// Needs polish, I know we just talked about Ochre conformance plz forgive
export const TextInputWithButton: React.FC =
React.memo(function TextInputWithButtonRaw({
@@ -85,27 +119,19 @@ export const TextInputWithButton: React.FC =
...textInputProps
}) {
return (
-
+
-
-
+
+
+ {buttonText}
+
+
+
);
});
diff --git a/packages/ui/src/components/GalleryPost/GalleryPost.tsx b/packages/ui/src/components/GalleryPost/GalleryPost.tsx
index ac75687e9b..7aa8d4bbe4 100644
--- a/packages/ui/src/components/GalleryPost/GalleryPost.tsx
+++ b/packages/ui/src/components/GalleryPost/GalleryPost.tsx
@@ -107,6 +107,8 @@ export function GalleryPostDetailView({ post }: { post: db.Post }) {
const formattedDate = useMemo(() => {
return makePrettyShortDate(new Date(post.receivedAt));
}, [post.receivedAt]);
+ const content = usePostContent(post);
+ const isImagePost = content.some((block) => block.type === 'image');
return (
@@ -114,14 +116,16 @@ export function GalleryPostDetailView({ post }: { post: db.Post }) {
-
+
{post.title && {post.title}}
- {formattedDate}
+ Added {formattedDate}
+
+ {isImagePost && }
);
@@ -264,6 +268,18 @@ const noWrapperPadding = {
},
} as const;
+const CaptionContentRenderer = createContentRenderer({
+ blockSettings: {
+ paragraph: {
+ size: '$body',
+ ...noWrapperPadding,
+ },
+ image: {
+ display: 'none',
+ },
+ },
+});
+
const LargeContentRenderer = createContentRenderer({
blockSettings: {
blockWrapper: {
diff --git a/packages/ui/src/components/GroupChannelsScreenView.tsx b/packages/ui/src/components/GroupChannelsScreenView.tsx
index f87cddbc76..b89ff31221 100644
--- a/packages/ui/src/components/GroupChannelsScreenView.tsx
+++ b/packages/ui/src/components/GroupChannelsScreenView.tsx
@@ -70,6 +70,14 @@ export function GroupChannelsScreenView({
[group]
);
+ const titleWidth = useCallback(() => {
+ if (isGroupAdmin) {
+ return 55;
+ } else {
+ return 75;
+ }
+ }, [isGroupAdmin]);
+
return (
diff --git a/packages/ui/src/components/GroupMembersScreenView.tsx b/packages/ui/src/components/GroupMembersScreenView.tsx
index 33986a7382..bbee14dc92 100644
--- a/packages/ui/src/components/GroupMembersScreenView.tsx
+++ b/packages/ui/src/components/GroupMembersScreenView.tsx
@@ -24,6 +24,7 @@ export function GroupMembersScreenView({
onPressUnban,
onPressAcceptJoinRequest,
onPressRejectJoinRequest,
+ onPressGoToDm,
}: {
goBack: () => void;
members: db.ChatMember[];
@@ -37,6 +38,7 @@ export function GroupMembersScreenView({
onPressUnban: (contactId: string) => void;
onPressAcceptJoinRequest: (contactId: string) => void;
onPressRejectJoinRequest: (contactId: string) => void;
+ onPressGoToDm: (contactId: string) => void;
}) {
const { bottom } = useSafeAreaInsets();
const [selectedContact, setSelectedContact] = useState(null);
@@ -207,6 +209,7 @@ export function GroupMembersScreenView({
onPressKick={() => onPressKick(selectedContact)}
onPressBan={() => onPressBan(selectedContact)}
onPressUnban={() => onPressUnban(selectedContact)}
+ onPressGoToDm={() => onPressGoToDm(selectedContact)}
/>
)}
{selectedContact !== null && selectedIsRequest && (
diff --git a/packages/ui/src/components/ListItem/ChannelListItem.tsx b/packages/ui/src/components/ListItem/ChannelListItem.tsx
index fdf1eb9b65..7365ac7d7c 100644
--- a/packages/ui/src/components/ListItem/ChannelListItem.tsx
+++ b/packages/ui/src/components/ListItem/ChannelListItem.tsx
@@ -53,23 +53,9 @@ export function ChannelListItem({
return (
-
+
-
- {title}
-
+ {title}
{customSubtitle ? (
{customSubtitle}
) : (
diff --git a/packages/ui/src/components/ListItem/GroupListItem.tsx b/packages/ui/src/components/ListItem/GroupListItem.tsx
index ae42a5825d..fa7a379000 100644
--- a/packages/ui/src/components/ListItem/GroupListItem.tsx
+++ b/packages/ui/src/components/ListItem/GroupListItem.tsx
@@ -28,20 +28,9 @@ export const GroupListItem = ({
onPress={useBoundHandler(model, onPress)}
onLongPress={useBoundHandler(model, onLongPress)}
>
-
+
-
- {title}
-
+ {title}
{customSubtitle && (
{customSubtitle}
)}
diff --git a/packages/ui/src/components/ListItem/ListItem.tsx b/packages/ui/src/components/ListItem/ListItem.tsx
index b8e5009c30..df282fc4d6 100644
--- a/packages/ui/src/components/ListItem/ListItem.tsx
+++ b/packages/ui/src/components/ListItem/ListItem.tsx
@@ -175,28 +175,26 @@ const ListItemCount = ({
return (
- {muted ? (
-
- ) : (
-
+
+ {muted && (
+
+ )}
+
{numberWithMax(count, 99)}
-
- )}
+
+
);
};
-const ListItemCountNumber = styled(SizableText, {
+const ListItemCountNumber = styled(XStack, {
name: 'ListItemCountNumber',
- size: '$s',
- color: '$secondaryText',
- textAlign: 'center',
+ gap: '$s',
+ alignItems: 'center',
variants: {
hidden: {
true: {
diff --git a/packages/ui/src/components/MessageInput/MessageInputBase.tsx b/packages/ui/src/components/MessageInput/MessageInputBase.tsx
index bbdac3fcfd..5c7a7d7188 100644
--- a/packages/ui/src/components/MessageInput/MessageInputBase.tsx
+++ b/packages/ui/src/components/MessageInput/MessageInputBase.tsx
@@ -1,8 +1,8 @@
import type { EditorBridge } from '@10play/tentap-editor';
-import { useCurrentSession } from '@tloncorp/shared/dist';
import * as db from '@tloncorp/shared/dist/db';
import { JSONContent, Story } from '@tloncorp/shared/dist/urbit';
import { ImagePickerAsset } from 'expo-image-picker';
+import { memo } from 'react';
import { PropsWithChildren } from 'react';
import { SpaceTokens } from 'tamagui';
import { ThemeTokens, View, XStack, YStack } from 'tamagui';
@@ -12,6 +12,7 @@ import { Button } from '../Button';
import { FloatingActionButton } from '../FloatingActionButton';
import { Icon } from '../Icon';
import { LoadingSpinner } from '../LoadingSpinner';
+import { GalleryDraftType } from '../draftInputs/shared';
import AttachmentButton from './AttachmentButton';
import InputMentionPopup from './InputMentionPopup';
@@ -25,9 +26,9 @@ export interface MessageInputProps {
) => Promise;
channelId: string;
groupMembers: db.ChatMember[];
- storeDraft: (draft: JSONContent) => void;
- clearDraft: () => void;
- getDraft: () => Promise;
+ storeDraft: (draft: JSONContent, draftType?: GalleryDraftType) => void;
+ clearDraft: (draftType?: GalleryDraftType) => void;
+ getDraft: (draftType?: GalleryDraftType) => Promise;
editingPost?: db.Post;
setEditingPost?: (post: db.Post | undefined) => void;
editPost?: (
@@ -43,6 +44,7 @@ export interface MessageInputProps {
backgroundColor?: ThemeTokens;
placeholder?: string;
bigInput?: boolean;
+ draftType?: GalleryDraftType;
title?: string;
image?: ImagePickerAsset;
showInlineAttachments?: boolean;
@@ -53,56 +55,54 @@ export interface MessageInputProps {
// for external access to height
setHeight?: (height: number) => void;
goBack?: () => void;
+ shouldAutoFocus?: boolean;
ref?: React.RefObject<{
editor: EditorBridge | null;
setEditor: (editor: EditorBridge) => void;
}>;
}
-export const MessageInputContainer = ({
- children,
- onPressSend,
- setShouldBlur,
- containerHeight,
- showMentionPopup = false,
- showAttachmentButton = true,
- floatingActionButton = false,
- disableSend = false,
- mentionText,
- groupMembers,
- onSelectMention,
- isSending,
- isEditing = false,
- cancelEditing,
- onPressEdit,
- goBack,
-}: PropsWithChildren<{
- setShouldBlur: (shouldBlur: boolean) => void;
- onPressSend: () => void;
- containerHeight: number;
- showMentionPopup?: boolean;
- showAttachmentButton?: boolean;
- floatingActionButton?: boolean;
- disableSend?: boolean;
- mentionText?: string;
- groupMembers: db.ChatMember[];
- onSelectMention: (contact: db.Contact) => void;
- isEditing?: boolean;
- isSending?: boolean;
- cancelEditing?: () => void;
- onPressEdit?: () => void;
- goBack?: () => void;
-}>) => {
- const currentSession = useCurrentSession();
- const isDisconnected =
- !currentSession || currentSession.isReconnecting === true;
- const { canUpload } = useAttachmentContext();
- if (isEditing) {
+export const MessageInputContainer = memo(
+ ({
+ children,
+ onPressSend,
+ setShouldBlur,
+ containerHeight,
+ showMentionPopup = false,
+ showAttachmentButton = true,
+ floatingActionButton = false,
+ disableSend = false,
+ mentionText,
+ groupMembers,
+ onSelectMention,
+ isSending,
+ isEditing = false,
+ cancelEditing,
+ onPressEdit,
+ goBack,
+ }: PropsWithChildren<{
+ setShouldBlur: (shouldBlur: boolean) => void;
+ onPressSend: () => void;
+ containerHeight: number;
+ showMentionPopup?: boolean;
+ showAttachmentButton?: boolean;
+ floatingActionButton?: boolean;
+ disableSend?: boolean;
+ mentionText?: string;
+ groupMembers: db.ChatMember[];
+ onSelectMention: (contact: db.Contact) => void;
+ isEditing?: boolean;
+ isSending?: boolean;
+ cancelEditing?: () => void;
+ onPressEdit?: () => void;
+ goBack?: () => void;
+ }>) => {
+ const { canUpload } = useAttachmentContext();
+
return (
-
+ {goBack ? (
+
+
+
+ ) : null}
+
+ {isEditing ? (
+ // using $2xs instead of $xs to match the padding of the attachment button
+ // might need to update the close icon?
+
+
+
+ ) : null}
+ {canUpload && showAttachmentButton ? (
+
+
+
+ ) : null}
{children}
-
-
-
+
+ ) : (
+
+
+
+ )}
);
}
+);
- return (
-
-
-
- {goBack ? (
-
-
-
- ) : null}
- {canUpload && showAttachmentButton ? (
-
-
-
- ) : null}
- {children}
- {floatingActionButton ? (
-
- {disableSend ? null : (
- }
- />
- )}
-
- ) : (
-
-
-
- )}
-
-
- );
-};
+MessageInputContainer.displayName = 'MessageInputContainer';
diff --git a/packages/ui/src/components/MessageInput/helpers.ts b/packages/ui/src/components/MessageInput/helpers.ts
index b42fd10e79..854cd917fe 100644
--- a/packages/ui/src/components/MessageInput/helpers.ts
+++ b/packages/ui/src/components/MessageInput/helpers.ts
@@ -4,6 +4,7 @@ import { createDevLogger, tiptap } from '@tloncorp/shared/dist';
import {
Block,
Inline,
+ JSONContent,
constructStory,
isInline,
} from '@tloncorp/shared/dist/urbit';
@@ -14,10 +15,12 @@ const logger = createDevLogger('processReference', true);
export async function processReferenceAndUpdateEditor({
editor,
+ editorJson,
pastedText,
matchRegex,
processMatch,
}: {
+ editorJson: JSONContent;
editor: EditorBridge | Editor;
pastedText: string;
matchRegex: RegExp;
@@ -29,14 +32,13 @@ export async function processReferenceAndUpdateEditor({
if (match) {
logger.log('found match', match[0]);
- const attachment = await processMatch(match[0]);
+ const attachment = processMatch(match[0]);
if (attachment) {
logger.log('extracted attachment', attachment);
// remove the attachments corresponding text from the editor
- const json = await editor.getJSON();
- const filteredJson = filterRegexFromJson(json, matchRegex);
+ const filteredJson = filterRegexFromJson(editorJson, matchRegex);
logger.log(`updating editor`, filteredJson);
if ('setContent' in editor) {
diff --git a/packages/ui/src/components/MessageInput/index.native.tsx b/packages/ui/src/components/MessageInput/index.native.tsx
index c5e93fcee5..58a3c2b7ad 100644
--- a/packages/ui/src/components/MessageInput/index.native.tsx
+++ b/packages/ui/src/components/MessageInput/index.native.tsx
@@ -133,10 +133,12 @@ export const MessageInput = forwardRef(
initialHeight = DEFAULT_MESSAGE_INPUT_HEIGHT,
placeholder = 'Message',
bigInput = false,
+ draftType,
title,
image,
channelType,
setHeight,
+ shouldAutoFocus,
goBack,
onSend,
},
@@ -209,9 +211,7 @@ export const MessageInput = forwardRef(
const editor = useEditorBridge({
customSource: editorHtml,
- // setting autofocus to true if we have editPost here doesn't seem to work
- // so we're using a useEffect to set it
- autofocus: false,
+ autofocus: shouldAutoFocus || false,
bridgeExtensions,
});
const editorState = useBridgeState(editor);
@@ -236,11 +236,13 @@ export const MessageInput = forwardRef(
}
}, [editor, ref]);
+ const lastEditingPost = useRef(editingPost);
+
useEffect(() => {
if (!hasSetInitialContent && editorState.isReady) {
try {
- getDraft().then((draft) => {
- if (draft) {
+ getDraft(draftType).then((draft) => {
+ if (!editingPost && draft) {
const inlines = tiptap.JSONToInlines(draft);
const newInlines = inlines
.map((inline) => {
@@ -255,12 +257,14 @@ export const MessageInput = forwardRef(
.filter((inline) => inline !== null) as Inline[];
const newStory = constructStory(newInlines);
const tiptapContent = tiptap.diaryMixedToJSON(newStory);
+ messageInputLogger.log('Setting draft content', tiptapContent);
// @ts-expect-error setContent does accept JSONContent
editor.setContent(tiptapContent);
setEditorIsEmpty(false);
}
- if (editingPost?.content) {
+ if (editingPost && editingPost.content) {
+ messageInputLogger.log('Editing post', editingPost);
const {
story,
references: postReferences,
@@ -303,8 +307,13 @@ export const MessageInput = forwardRef(
(c) => !('type' in c) && !('block' in c && 'image' in c.block)
) as Story
);
+ messageInputLogger.log(
+ 'Setting edit post content',
+ tiptapContent
+ );
// @ts-expect-error setContent does accept JSONContent
editor.setContent(tiptapContent);
+ setEditorIsEmpty(false);
}
if (editingPost?.image) {
@@ -327,6 +336,7 @@ export const MessageInput = forwardRef(
}, [
editor,
getDraft,
+ draftType,
hasSetInitialContent,
editorState.isReady,
editingPost,
@@ -335,10 +345,18 @@ export const MessageInput = forwardRef(
]);
useEffect(() => {
- if (editor && !shouldBlur && !editorState.isFocused && !!editingPost) {
+ if (editingPost && lastEditingPost.current?.id !== editingPost.id) {
+ messageInputLogger.log('Editing post changed', editingPost);
+ lastEditingPost.current = editingPost;
+ setHasSetInitialContent(false);
+ }
+ }, [editingPost]);
+
+ useEffect(() => {
+ if (editor && !shouldBlur && shouldAutoFocus && !editorState.isFocused) {
editor.focus();
}
- }, [shouldBlur, editor, editorState, editingPost]);
+ }, [shouldAutoFocus, editor, editorState, shouldBlur]);
useEffect(() => {
if (editor && shouldBlur && editorState.isFocused) {
@@ -348,6 +366,8 @@ export const MessageInput = forwardRef(
}, [shouldBlur, editor, editorState, setShouldBlur]);
useEffect(() => {
+ messageInputLogger.log('Checking if editor is empty');
+
editor.getJSON().then((json: JSONContent) => {
const inlines = tiptap
.JSONToInlines(json)
@@ -372,13 +392,21 @@ export const MessageInput = forwardRef(
blocks.length === 0 &&
attachments.length === 0;
+ messageInputLogger.log('Editor is empty?', isEmpty);
+
if (isEmpty !== editorIsEmpty) {
+ messageInputLogger.log('Setting editorIsEmpty', isEmpty);
setEditorIsEmpty(isEmpty);
+ setContainerHeight(initialHeight);
}
});
- }, [editor, attachments, editorIsEmpty]);
+ }, [editor, attachments, editorIsEmpty, initialHeight]);
editor._onContentUpdate = async () => {
+ messageInputLogger.log(
+ 'Content updated, update draft and check for mention text'
+ );
+
const json = await editor.getJSON();
const inlines = (
tiptap
@@ -393,25 +421,32 @@ export const MessageInput = forwardRef(
(inline) => typeof inline === 'string' && inline.match(/\B[~@]/)
) as string | undefined;
// extract the mention text from the mention inline
- const mentionText = mentionInline
+ const mentionTextFromInline = mentionInline
? mentionInline.slice((mentionInline.match(/\B[~@]/)?.index ?? -1) + 1)
: null;
- if (mentionText !== null) {
+ if (mentionTextFromInline !== null) {
+ messageInputLogger.log('Mention text', mentionTextFromInline);
// if we have a mention text, we show the mention popup
setShowMentionPopup(true);
- setMentionText(mentionText);
+ setMentionText(mentionTextFromInline);
} else {
setShowMentionPopup(false);
+ setMentionText('');
}
- storeDraft(json);
+ messageInputLogger.log('Storing draft', json);
+
+ storeDraft(json, draftType);
};
const handlePaste = useCallback(
async (pastedText: string) => {
+ messageInputLogger.log('Pasted text', pastedText);
// check for ref from pasted cite paths
+ const editorJson = await editor.getJSON();
const citePathAttachment = await processReferenceAndUpdateEditor({
editor,
+ editorJson,
pastedText,
matchRegex: tiptap.REF_REGEX,
processMatch: async (match) => {
@@ -433,6 +468,7 @@ export const MessageInput = forwardRef(
const DEEPLINK_REGEX = new RegExp(`^(https?://)?${branchDomain}/\\S+$`);
const deepLinkAttachment = await processReferenceAndUpdateEditor({
editor,
+ editorJson,
pastedText,
matchRegex: DEEPLINK_REGEX,
processMatch: async (deeplink) => {
@@ -458,6 +494,7 @@ export const MessageInput = forwardRef(
/^(https?:\/\/)?(tlon\.network\/lure\/)(0v[^/]+)$/;
const lureLinkAttachment = await processReferenceAndUpdateEditor({
editor,
+ editorJson,
pastedText,
matchRegex: TLON_LURE_REGEX,
processMatch: async (tlonLure) => {
@@ -486,6 +523,7 @@ export const MessageInput = forwardRef(
const onSelectMention = useCallback(
async (contact: db.Contact) => {
+ messageInputLogger.log('Selected mention', contact);
const json = await editor.getJSON();
const inlines = tiptap.JSONToInlines(json);
@@ -540,13 +578,27 @@ export const MessageInput = forwardRef(
const newJson = tiptap.diaryMixedToJSON(newStory);
+ // insert empty text node after mention
+ newJson.content?.map((node) => {
+ const containsMention = node.content?.some(
+ (n) => n.type === 'mention'
+ );
+ if (containsMention) {
+ node.content?.push({
+ type: 'text',
+ text: ' ',
+ });
+ }
+ });
+
+ messageInputLogger.log('onSelectMention, setting new content', newJson);
// @ts-expect-error setContent does accept JSONContent
editor.setContent(newJson);
- storeDraft(newJson);
+ storeDraft(newJson, draftType);
setMentionText('');
setShowMentionPopup(false);
},
- [editor, storeDraft]
+ [editor, storeDraft, draftType]
);
const sendMessage = useCallback(
@@ -644,7 +696,7 @@ export const MessageInput = forwardRef(
onSend?.();
editor.setContent('');
clearAttachments();
- clearDraft();
+ clearDraft(draftType);
setShowBigInput?.(false);
},
[
@@ -662,6 +714,7 @@ export const MessageInput = forwardRef(
channelType,
send,
channelId,
+ draftType,
]
);
@@ -844,6 +897,13 @@ export const MessageInput = forwardRef(
const titleIsEmpty = useMemo(() => !title || title.length === 0, [title]);
+ const handleCancelEditing = useCallback(() => {
+ setEditingPost?.(undefined);
+ editor.setContent('');
+ clearDraft(draftType);
+ clearAttachments();
+ }, [setEditingPost, editor, clearDraft, clearAttachments, draftType]);
+
return (
(
showMentionPopup={showMentionPopup}
isEditing={!!editingPost}
isSending={isSending}
- cancelEditing={() => setEditingPost?.(undefined)}
+ cancelEditing={handleCancelEditing}
showAttachmentButton={showAttachmentButton}
floatingActionButton={floatingActionButton}
disableSend={
diff --git a/packages/ui/src/components/MetaEditorScreenView.tsx b/packages/ui/src/components/MetaEditorScreenView.tsx
index 575f08e533..ba66c0af9b 100644
--- a/packages/ui/src/components/MetaEditorScreenView.tsx
+++ b/packages/ui/src/components/MetaEditorScreenView.tsx
@@ -56,7 +56,7 @@ export function MetaEditorScreenView({
}, [chat, modelLoaded, reset, defaultValues]);
const runSubmit = useCallback(
- () => handleSubmit(onSubmit),
+ () => handleSubmit(onSubmit)(),
[handleSubmit, onSubmit]
);
diff --git a/packages/ui/src/components/Onboarding/OnboardingBenefitsSheet.tsx b/packages/ui/src/components/Onboarding/OnboardingBenefitsSheet.tsx
new file mode 100644
index 0000000000..2ec013305f
--- /dev/null
+++ b/packages/ui/src/components/Onboarding/OnboardingBenefitsSheet.tsx
@@ -0,0 +1,94 @@
+import { ActionSheet, Icon, Image, View, XStack, YStack } from '@tloncorp/ui';
+
+import { Text } from '../TextV2';
+
+export function OnboardingBenefitsSheet({
+ open,
+ onOpenChange,
+}: {
+ open: boolean;
+ onOpenChange: (isOpen: boolean) => void;
+}) {
+ return (
+
+
+
+
+
+
+
+
+
+ Welcome to TM
+
+
+ A messenger you can actually trust.
+
+
+
+
+
+
+
+
+
+
+
+ Tlon operates on a peer-to-peer network.
+
+
+ Practically, this means your free account is a cloud computer.
+ You can run it yourself, or we can run it for you.
+
+
+
+
+
+
+
+
+
+
+
+ Hassle-free messaging you can trust.
+
+ We’ll make sure your computer is online and up-to-date.
+ Interested in self-hosting? You can always change your mind.
+
+
+
+
+
+
+
+
+
+
+
+ Sign up with your email address.
+
+ We’ll ask you a few questions to get you set up.
+
+
+
+
+
+
+ );
+}
diff --git a/packages/ui/src/components/Onboarding/OnboardingButton.tsx b/packages/ui/src/components/Onboarding/OnboardingButton.tsx
new file mode 100644
index 0000000000..e43a53820b
--- /dev/null
+++ b/packages/ui/src/components/Onboarding/OnboardingButton.tsx
@@ -0,0 +1,36 @@
+import { ComponentProps, PropsWithChildren } from 'react';
+import { View } from 'tamagui';
+
+import { Button } from '../Button';
+
+export function OnboardingButton({
+ secondary,
+ ...props
+}: ComponentProps & {
+ secondary?: boolean;
+}) {
+ const color = secondary ? '$secondaryText' : '$primaryText';
+ return (
+
+ );
+}
+
+export function OnboardingButtonWrapper({ children }: PropsWithChildren) {
+ return (
+
+ {children}
+
+ );
+}
diff --git a/packages/ui/src/components/Onboarding/OnboardingContent.tsx b/packages/ui/src/components/Onboarding/OnboardingContent.tsx
new file mode 100644
index 0000000000..391de25db1
--- /dev/null
+++ b/packages/ui/src/components/Onboarding/OnboardingContent.tsx
@@ -0,0 +1,6 @@
+import { YStack, styled } from 'tamagui';
+
+export const OnboardingTextBlock = styled(YStack, {
+ padding: '$xl',
+ gap: '$3xl',
+});
diff --git a/packages/ui/src/components/AppInviteDisplay.tsx b/packages/ui/src/components/Onboarding/OnboardingInvite.tsx
similarity index 74%
rename from packages/ui/src/components/AppInviteDisplay.tsx
rename to packages/ui/src/components/Onboarding/OnboardingInvite.tsx
index 193a59d14a..b926d7f201 100644
--- a/packages/ui/src/components/AppInviteDisplay.tsx
+++ b/packages/ui/src/components/Onboarding/OnboardingInvite.tsx
@@ -1,10 +1,10 @@
import { DeepLinkMetadata } from '@tloncorp/shared/dist';
import React, { ComponentProps } from 'react';
-import { AppDataContextProvider } from '../contexts';
-import { ListItem } from './ListItem';
+import { AppDataContextProvider } from '../../contexts';
+import { ListItem } from '../ListItem';
-function AppInviteDisplayRaw({
+export const OnboardingInviteBlock = React.memo(function OnboardingInviteBlock({
metadata,
...rest
}: { metadata: DeepLinkMetadata } & ComponentProps) {
@@ -31,8 +31,17 @@ function AppInviteDisplayRaw({
return (
// provider needed to support calm settings usage down the tree
-
+
@@ -47,6 +56,4 @@ function AppInviteDisplayRaw({
);
-}
-
-export const AppInviteDisplay = React.memo(AppInviteDisplayRaw);
+});
diff --git a/packages/ui/src/components/Onboarding/index.tsx b/packages/ui/src/components/Onboarding/index.tsx
new file mode 100644
index 0000000000..4dacac25b9
--- /dev/null
+++ b/packages/ui/src/components/Onboarding/index.tsx
@@ -0,0 +1,3 @@
+export * from './OnboardingButton';
+export * from './OnboardingInvite';
+export * from './OnboardingContent';
diff --git a/packages/ui/src/components/PostScreenView.tsx b/packages/ui/src/components/PostScreenView.tsx
index da1d975c60..e3f5440e1f 100644
--- a/packages/ui/src/components/PostScreenView.tsx
+++ b/packages/ui/src/components/PostScreenView.tsx
@@ -22,6 +22,7 @@ export function PostScreenView({
initialThreadUnread,
parentPost,
posts,
+ isLoadingPosts,
sendReply,
markRead,
goBack,
@@ -46,6 +47,7 @@ export function PostScreenView({
group?: db.Group | null;
parentPost: db.Post | null;
posts: db.Post[] | null;
+ isLoadingPosts: boolean;
sendReply: (content: urbit.Story, channelId: string) => Promise;
markRead: () => void;
goBack?: () => void;
@@ -110,6 +112,7 @@ export function PostScreenView({
title={headerTitle}
goBack={goBack}
showSearchButton={false}
+ showSpinner={isLoadingPosts}
post={parentPost ?? undefined}
mode={headerMode}
/>
@@ -121,7 +124,6 @@ export function PostScreenView({
onPressImage={handleGoToImage}
editingPost={editingPost}
setEditingPost={setEditingPost}
- editPost={editPost}
onPressRetry={onPressRetry}
onPressDelete={onPressDelete}
posts={postsWithoutParent}
@@ -132,7 +134,7 @@ export function PostScreenView({
/>
) : null}
- {negotiationMatch && !editingPost && channel && canWrite && (
+ {negotiationMatch && channel && canWrite && (
)}
{!negotiationMatch && channel && canWrite && (
diff --git a/packages/ui/src/components/ProfileBlock.tsx b/packages/ui/src/components/ProfileBlock.tsx
index 087787a026..3ea37082fc 100644
--- a/packages/ui/src/components/ProfileBlock.tsx
+++ b/packages/ui/src/components/ProfileBlock.tsx
@@ -14,12 +14,7 @@ export const ProfileBlock = ({
>) => {
const contact = useContact(contactId);
return contact?.coverImage ? (
-
+
void;
onPressBan?: () => void;
onPressUnban?: () => void;
+ onPressGoToDm?: () => void;
}) {
const currentUserId = useCurrentUserId();
- const { onPressGoToDm } = useNavigation();
-
const handleBlock = useCallback(() => {
if (contact && contact.isBlocked) {
store.unblockUser(contactId);
@@ -63,11 +61,6 @@ export function ProfileSheet({
onOpenChange(false);
}, [contact, contactId, onOpenChange]);
- const handleGoToDm = useCallback(async () => {
- onPressGoToDm?.([contactId]);
- onOpenChange(false);
- }, [contactId, onPressGoToDm, onOpenChange]);
-
const isAdminnable = currentUserIsAdmin && currentUserId !== contactId;
const actions: ActionGroup[] = createActionGroups(
@@ -75,7 +68,10 @@ export function ProfileSheet({
'neutral',
{
title: 'Send message',
- action: () => handleGoToDm,
+ action: () => {
+ onPressGoToDm?.();
+ onOpenChange(false);
+ },
endIcon: 'ChevronRight',
},
{
@@ -119,8 +115,6 @@ export function ProfileSheet({
diff --git a/packages/ui/src/components/ScreenHeader.tsx b/packages/ui/src/components/ScreenHeader.tsx
index d848ee3eb5..6fc6fc2a68 100644
--- a/packages/ui/src/components/ScreenHeader.tsx
+++ b/packages/ui/src/components/ScreenHeader.tsx
@@ -16,6 +16,7 @@ import { Text } from './TextV2';
export const ScreenHeaderComponent = ({
children,
title,
+ titleWidth = 100,
leftControls,
rightControls,
isLoading,
@@ -23,6 +24,7 @@ export const ScreenHeaderComponent = ({
showSessionStatus,
}: PropsWithChildren<{
title?: string | ReactNode;
+ titleWidth?: 100 | 75 | 55;
leftControls?: ReactNode | null;
rightControls?: ReactNode | null;
isLoading?: boolean;
@@ -42,13 +44,18 @@ export const ScreenHeaderComponent = ({
return (
{typeof resolvedTitle === 'string' ? (
-
+
) : (
resolvedTitle
)}
@@ -79,6 +86,13 @@ const HeaderTextButton = styled(Text, {
pressStyle: {
opacity: 0.5,
},
+ variants: {
+ disabled: {
+ true: {
+ color: '$tertiaryText',
+ },
+ },
+ },
});
const HeaderBackButton = ({ onPress }: { onPress?: () => void }) => {
@@ -95,9 +109,11 @@ const HeaderTitleText = styled(Text, {
function HeaderTitle({
title,
+ titleWidth = 100,
...props
}: {
title: string;
+ titleWidth?: 100 | 75 | 55;
} & ComponentProps) {
const hasMounted = useHasMounted();
const renderedTitle = {title};
@@ -111,7 +127,10 @@ function HeaderTitle({
// it first enters.
entering={hasMounted ? FadeInDown : undefined}
exiting={FadeOutUp}
- style={{ flex: 1 }}
+ style={{
+ flex: 1,
+ maxWidth: `${titleWidth}%`,
+ }}
>
{renderedTitle}
diff --git a/packages/ui/src/components/SendPostRetrySheet.tsx b/packages/ui/src/components/SendPostRetrySheet.tsx
index bc1804e9f9..d58a05df79 100644
--- a/packages/ui/src/components/SendPostRetrySheet.tsx
+++ b/packages/ui/src/components/SendPostRetrySheet.tsx
@@ -22,6 +22,7 @@ export const SendPostRetrySheet = ({
{
title: 'Delete',
action: onPressDelete,
+ accent: 'negative'
},
],
[onPressRetry, onPressDelete]
diff --git a/packages/ui/src/components/WelcomeSheet.tsx b/packages/ui/src/components/WelcomeSheet.tsx
index 762605ea7f..29abd49c73 100644
--- a/packages/ui/src/components/WelcomeSheet.tsx
+++ b/packages/ui/src/components/WelcomeSheet.tsx
@@ -45,7 +45,7 @@ function WelcomeSheetComponent({
/>
- Welcome to Tlon
+ Welcome to TM
A messenger you can finally trust.
diff --git a/packages/ui/src/components/WelcomeSheet.web.tsx b/packages/ui/src/components/WelcomeSheet.web.tsx
index d3f7973a94..302751b0c6 100644
--- a/packages/ui/src/components/WelcomeSheet.web.tsx
+++ b/packages/ui/src/components/WelcomeSheet.web.tsx
@@ -43,7 +43,7 @@ function WelcomeSheetComponent({
/>
- Welcome to Tlon
+ Welcome to TM
A messenger you can finally trust.
diff --git a/packages/ui/src/components/draftInputs/ChatInput.tsx b/packages/ui/src/components/draftInputs/ChatInput.tsx
index fe01d11441..7ce1dc2fea 100644
--- a/packages/ui/src/components/draftInputs/ChatInput.tsx
+++ b/packages/ui/src/components/draftInputs/ChatInput.tsx
@@ -22,9 +22,6 @@ export function ChatInput({
shouldBlur,
storeDraft,
} = draftInputContext;
- if (editingPost != null) {
- return null;
- }
return (
@@ -42,6 +39,7 @@ export function ChatInput({
setEditingPost={setEditingPost}
editPost={editPost}
channelType={channel.type}
+ shouldAutoFocus={!!editingPost}
showInlineAttachments
showAttachmentButton
/>
diff --git a/packages/ui/src/components/draftInputs/GalleryInput.tsx b/packages/ui/src/components/draftInputs/GalleryInput.tsx
index cf456f5833..ec7d71eda4 100644
--- a/packages/ui/src/components/draftInputs/GalleryInput.tsx
+++ b/packages/ui/src/components/draftInputs/GalleryInput.tsx
@@ -76,6 +76,7 @@ export function GalleryInput({
() =>
showBigInput ? null : (
setShowAddGalleryPost(true)}
/>
@@ -135,6 +136,7 @@ export function GalleryInput({
groupMembers={group?.members ?? []}
storeDraft={storeDraft}
clearDraft={clearDraft}
+ draftType="caption"
getDraft={getDraft}
editingPost={editingPost}
setEditingPost={setEditingPost}
diff --git a/packages/ui/src/components/draftInputs/NotebookInput.tsx b/packages/ui/src/components/draftInputs/NotebookInput.tsx
index f7637239d2..4b4a95a0d5 100644
--- a/packages/ui/src/components/draftInputs/NotebookInput.tsx
+++ b/packages/ui/src/components/draftInputs/NotebookInput.tsx
@@ -39,6 +39,7 @@ export function NotebookInput({
() =>
showBigInput ? null : (
setShowBigInput(true)}
/>
diff --git a/packages/ui/src/components/draftInputs/shared.ts b/packages/ui/src/components/draftInputs/shared.ts
index d95efe7109..4f4519a163 100644
--- a/packages/ui/src/components/draftInputs/shared.ts
+++ b/packages/ui/src/components/draftInputs/shared.ts
@@ -2,6 +2,8 @@ import * as db from '@tloncorp/shared/dist/db';
import { JSONContent, Story } from '@tloncorp/shared/dist/urbit';
import { Dispatch, SetStateAction } from 'react';
+export type GalleryDraftType = 'caption' | 'text';
+
export interface DraftInputHandle {
/**
* @deprecated
@@ -19,11 +21,11 @@ export interface DraftInputHandle {
*/
export interface DraftInputContext {
channel: db.Channel;
- clearDraft: () => void;
+ clearDraft: (draftType?: GalleryDraftType) => void;
draftInputRef?: React.Ref;
editPost: (post: db.Post, content: Story) => Promise;
editingPost?: db.Post;
- getDraft: () => Promise;
+ getDraft: (draftType?: GalleryDraftType) => Promise;
group: db.Group | null;
headerMode: 'default' | 'next';
@@ -45,5 +47,5 @@ export interface DraftInputContext {
setEditingPost?: (update: db.Post | undefined) => void;
setShouldBlur: Dispatch>;
shouldBlur: boolean;
- storeDraft: (content: JSONContent) => void;
+ storeDraft: (content: JSONContent, draftType?: GalleryDraftType) => void;
}
diff --git a/packages/ui/src/index.tsx b/packages/ui/src/index.tsx
index a81eea3b16..7d4a1e50e2 100644
--- a/packages/ui/src/index.tsx
+++ b/packages/ui/src/index.tsx
@@ -59,6 +59,7 @@ export * from './components/MessageInput/AttachmentPreviewList';
export * from './components/NavBarView';
export * from './components/Modal';
export * from './components/NavBar';
+export * from './components/Onboarding';
export * from './components/ParentAgnosticKeyboardAvoidingView';
export * from './components/PostScreenView';
export * from './components/ProfileScreenView';
@@ -72,11 +73,13 @@ export * from './components/UrbitSigil';
export * from './components/UserProfileScreenView';
export * from './components/View';
export * from './components/WelcomeSheet';
-export * from './components/AppInviteDisplay';
+export * from './components/Image';
+export * as Form from './components/Form';
export * from './contexts';
export * from './tamagui.config';
export * from './types';
export * from './utils';
+export * as TlonText from './components/TextV2';
export {
Circle,
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 0bc0e15f4c..3db8c4cee5 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -92,7 +92,7 @@ importers:
version: 8.0.1(@swc/core@1.7.26(@swc/helpers@0.5.13))(postcss@8.4.35)(typescript@5.4.5)
vitest:
specifier: ^1.2.2
- version: 1.2.2(@types/node@20.14.10)(jsdom@23.2.0)(lightningcss@1.19.0)(terser@5.19.1)
+ version: 1.2.2(@types/node@20.14.10)(jsdom@23.2.0)(terser@5.19.1)
apps/tlon-mobile:
dependencies:
@@ -257,7 +257,7 @@ importers:
version: 4.17.21
posthog-react-native:
specifier: ^2.7.1
- version: 2.11.3(@react-native-async-storage/async-storage@1.21.0(react-native@0.73.9(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2))(encoding@0.1.13)(react@18.2.0)))(@react-navigation/native@6.1.10(react-native@0.73.9(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2))(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(expo-application@5.8.3(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13)))(expo-device@5.9.3(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13)))(expo-file-system@16.0.9(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13)))(expo-localization@14.8.3(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13)))(react-native-device-info@10.12.0(react-native@0.73.9(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2))(encoding@0.1.13)(react@18.2.0)))
+ version: 2.11.3(jwrxiw3lzqzjxcpw4mvkvmmdfa)
react:
specifier: ^18.2.0
version: 18.2.0
@@ -426,7 +426,7 @@ importers:
version: 3.4.1
vitest:
specifier: ^1.0.4
- version: 1.2.2(@types/node@20.14.10)(jsdom@23.2.0)(lightningcss@1.19.0)(terser@5.19.1)
+ version: 1.2.2(@types/node@20.14.10)(jsdom@23.2.0)(terser@5.19.1)
apps/tlon-web:
dependencies:
@@ -476,8 +476,8 @@ importers:
specifier: ^1.0.0
version: 1.0.0(@types/react@18.2.55)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
'@tamagui/vite-plugin':
- specifier: ~1.112.12
- version: 1.112.12(@swc/helpers@0.5.13)(encoding@0.1.13)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ specifier: ~1.101.3
+ version: 1.101.3(encoding@0.1.13)(react@18.2.0)
'@tanstack/react-query':
specifier: ^4.28.0
version: 4.36.1(react-dom@18.2.0(react@18.2.0))(react-native@0.73.9(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2))(encoding@0.1.13)(react@18.2.0))(react@18.2.0)
@@ -798,7 +798,7 @@ importers:
version: 0.16.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
vite-plugin-svgr:
specifier: ^4.2.0
- version: 4.2.0(rollup@4.13.0)(typescript@5.4.5)(vite@5.1.6(@types/node@20.10.8)(lightningcss@1.19.0)(terser@5.19.1))
+ version: 4.2.0(rollup@2.79.1)(typescript@5.4.5)(vite@5.1.6(@types/node@20.10.8)(terser@5.19.1))
workbox-precaching:
specifier: ^6.5.4
version: 6.6.0
@@ -889,10 +889,10 @@ importers:
version: 2.0.1
'@vitejs/plugin-basic-ssl':
specifier: ^1.1.0
- version: 1.1.0(vite@5.1.6(@types/node@20.10.8)(lightningcss@1.19.0)(terser@5.19.1))
+ version: 1.1.0(vite@5.1.6(@types/node@20.10.8)(terser@5.19.1))
'@vitejs/plugin-react':
specifier: ^4.2.1
- version: 4.2.1(vite@5.1.6(@types/node@20.10.8)(lightningcss@1.19.0)(terser@5.19.1))
+ version: 4.2.1(vite@5.1.6(@types/node@20.10.8)(terser@5.19.1))
'@welldone-software/why-did-you-render':
specifier: ^7.0.1
version: 7.0.1(react@18.2.0)
@@ -934,7 +934,7 @@ importers:
version: 6.1.1
react-cosmos-plugin-vite:
specifier: 6.1.1
- version: 6.1.1(vite@5.1.6(@types/node@20.10.8)(lightningcss@1.19.0)(terser@5.19.1))
+ version: 6.1.1(vite@5.1.6(@types/node@20.10.8)(terser@5.19.1))
react-test-renderer:
specifier: ^18.2.0
version: 18.2.0(react@18.2.0)
@@ -943,7 +943,7 @@ importers:
version: 4.0.0
rollup-plugin-visualizer:
specifier: ^5.6.0
- version: 5.12.0(rollup@4.13.0)
+ version: 5.12.0(rollup@2.79.1)
tailwindcss:
specifier: ^3.2.7
version: 3.4.1
@@ -958,13 +958,13 @@ importers:
version: 1.1.4(typescript@5.4.5)
vite:
specifier: ^5.1.6
- version: 5.1.6(@types/node@20.10.8)(lightningcss@1.19.0)(terser@5.19.1)
+ version: 5.1.6(@types/node@20.10.8)(terser@5.19.1)
vite-plugin-pwa:
specifier: ^0.17.5
- version: 0.17.5(vite@5.1.6(@types/node@20.10.8)(lightningcss@1.19.0)(terser@5.19.1))(workbox-build@7.0.0(@types/babel__core@7.20.5))(workbox-window@7.0.0)
+ version: 0.17.5(vite@5.1.6(@types/node@20.10.8)(terser@5.19.1))(workbox-build@7.0.0(@types/babel__core@7.20.5))(workbox-window@7.0.0)
vitest:
specifier: ^0.34.1
- version: 0.34.6(jsdom@23.2.0)(lightningcss@1.19.0)(terser@5.19.1)
+ version: 0.34.6(jsdom@23.2.0)(terser@5.19.1)
workbox-window:
specifier: ^7.0.0
version: 7.0.0
@@ -1348,7 +1348,7 @@ importers:
version: 0.16.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
vite-plugin-svgr:
specifier: ^4.2.0
- version: 4.2.0(rollup@4.13.0)(typescript@5.4.5)(vite@5.1.6(@types/node@20.14.10)(lightningcss@1.19.0)(terser@5.19.1))
+ version: 4.2.0(rollup@4.13.0)(typescript@5.4.5)(vite@5.1.6(@types/node@20.14.10)(terser@5.19.1))
workbox-precaching:
specifier: ^6.5.4
version: 6.6.0
@@ -1442,10 +1442,10 @@ importers:
version: 2.0.1
'@vitejs/plugin-basic-ssl':
specifier: ^1.1.0
- version: 1.1.0(vite@5.1.6(@types/node@20.14.10)(lightningcss@1.19.0)(terser@5.19.1))
+ version: 1.1.0(vite@5.1.6(@types/node@20.14.10)(terser@5.19.1))
'@vitejs/plugin-react':
specifier: ^4.2.1
- version: 4.2.1(vite@5.1.6(@types/node@20.14.10)(lightningcss@1.19.0)(terser@5.19.1))
+ version: 4.2.1(vite@5.1.6(@types/node@20.14.10)(terser@5.19.1))
'@welldone-software/why-did-you-render':
specifier: ^7.0.1
version: 7.0.1(react@18.2.0)
@@ -1490,7 +1490,7 @@ importers:
version: 6.1.1
react-cosmos-plugin-vite:
specifier: 6.1.1
- version: 6.1.1(vite@5.1.6(@types/node@20.14.10)(lightningcss@1.19.0)(terser@5.19.1))
+ version: 6.1.1(vite@5.1.6(@types/node@20.14.10)(terser@5.19.1))
react-test-renderer:
specifier: ^18.2.0
version: 18.2.0(react@18.2.0)
@@ -1514,13 +1514,13 @@ importers:
version: 1.1.4(typescript@5.4.5)
vite:
specifier: ^5.1.6
- version: 5.1.6(@types/node@20.14.10)(lightningcss@1.19.0)(terser@5.19.1)
+ version: 5.1.6(@types/node@20.14.10)(terser@5.19.1)
vite-plugin-pwa:
specifier: ^0.17.5
- version: 0.17.5(vite@5.1.6(@types/node@20.14.10)(lightningcss@1.19.0)(terser@5.19.1))(workbox-build@7.0.0(@types/babel__core@7.20.5))(workbox-window@7.0.0)
+ version: 0.17.5(vite@5.1.6(@types/node@20.14.10)(terser@5.19.1))(workbox-build@7.0.0(@types/babel__core@7.20.5))(workbox-window@7.0.0)
vitest:
specifier: ^0.34.1
- version: 0.34.6(jsdom@23.2.0)(lightningcss@1.19.0)(terser@5.19.1)
+ version: 0.34.6(jsdom@23.2.0)(terser@5.19.1)
workbox-window:
specifier: ^7.0.0
version: 7.0.0
@@ -1585,7 +1585,7 @@ importers:
version: 6.21.0(eslint@8.56.0)(typescript@5.4.5)
'@vitejs/plugin-react':
specifier: ^4.2.1
- version: 4.2.1(vite@5.1.6(@types/node@20.14.10)(lightningcss@1.19.0)(terser@5.19.1))
+ version: 4.2.1(vite@5.1.6(@types/node@20.14.10)(terser@5.19.1))
eslint:
specifier: ^8.50.0
version: 8.56.0
@@ -1597,13 +1597,13 @@ importers:
version: 5.4.5
vite:
specifier: ^5.1.6
- version: 5.1.6(@types/node@20.14.10)(lightningcss@1.19.0)(terser@5.19.1)
+ version: 5.1.6(@types/node@20.14.10)(terser@5.19.1)
vite-plugin-singlefile:
specifier: ^2.0.1
- version: 2.0.1(rollup@4.13.0)(vite@5.1.6(@types/node@20.14.10)(lightningcss@1.19.0)(terser@5.19.1))
+ version: 2.0.1(rollup@4.13.0)(vite@5.1.6(@types/node@20.14.10)(terser@5.19.1))
vitest:
specifier: ^1.0.4
- version: 1.5.0(@types/node@20.14.10)(jsdom@23.2.0)(lightningcss@1.19.0)(terser@5.19.1)
+ version: 1.5.0(@types/node@20.14.10)(jsdom@23.2.0)(terser@5.19.1)
packages/shared:
dependencies:
@@ -1671,7 +1671,7 @@ importers:
version: 5.4.5
vitest:
specifier: ^1.4.0
- version: 1.5.0(@types/node@20.14.10)(jsdom@23.2.0)(lightningcss@1.19.0)(terser@5.19.1)
+ version: 1.5.0(@types/node@20.14.10)(jsdom@23.2.0)(terser@5.19.1)
packages/ui:
dependencies:
@@ -3147,6 +3147,12 @@ packages:
cpu: [ppc64]
os: [aix]
+ '@esbuild/aix-ppc64@0.21.5':
+ resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==}
+ engines: {node: '>=12'}
+ cpu: [ppc64]
+ os: [aix]
+
'@esbuild/aix-ppc64@0.24.0':
resolution: {integrity: sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==}
engines: {node: '>=18'}
@@ -3165,6 +3171,12 @@ packages:
cpu: [arm64]
os: [android]
+ '@esbuild/android-arm64@0.21.5':
+ resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [android]
+
'@esbuild/android-arm64@0.24.0':
resolution: {integrity: sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==}
engines: {node: '>=18'}
@@ -3183,6 +3195,12 @@ packages:
cpu: [arm]
os: [android]
+ '@esbuild/android-arm@0.21.5':
+ resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==}
+ engines: {node: '>=12'}
+ cpu: [arm]
+ os: [android]
+
'@esbuild/android-arm@0.24.0':
resolution: {integrity: sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==}
engines: {node: '>=18'}
@@ -3201,6 +3219,12 @@ packages:
cpu: [x64]
os: [android]
+ '@esbuild/android-x64@0.21.5':
+ resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [android]
+
'@esbuild/android-x64@0.24.0':
resolution: {integrity: sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==}
engines: {node: '>=18'}
@@ -3219,6 +3243,12 @@ packages:
cpu: [arm64]
os: [darwin]
+ '@esbuild/darwin-arm64@0.21.5':
+ resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [darwin]
+
'@esbuild/darwin-arm64@0.24.0':
resolution: {integrity: sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==}
engines: {node: '>=18'}
@@ -3237,6 +3267,12 @@ packages:
cpu: [x64]
os: [darwin]
+ '@esbuild/darwin-x64@0.21.5':
+ resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [darwin]
+
'@esbuild/darwin-x64@0.24.0':
resolution: {integrity: sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==}
engines: {node: '>=18'}
@@ -3255,6 +3291,12 @@ packages:
cpu: [arm64]
os: [freebsd]
+ '@esbuild/freebsd-arm64@0.21.5':
+ resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [freebsd]
+
'@esbuild/freebsd-arm64@0.24.0':
resolution: {integrity: sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==}
engines: {node: '>=18'}
@@ -3273,6 +3315,12 @@ packages:
cpu: [x64]
os: [freebsd]
+ '@esbuild/freebsd-x64@0.21.5':
+ resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [freebsd]
+
'@esbuild/freebsd-x64@0.24.0':
resolution: {integrity: sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==}
engines: {node: '>=18'}
@@ -3291,6 +3339,12 @@ packages:
cpu: [arm64]
os: [linux]
+ '@esbuild/linux-arm64@0.21.5':
+ resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [linux]
+
'@esbuild/linux-arm64@0.24.0':
resolution: {integrity: sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==}
engines: {node: '>=18'}
@@ -3309,6 +3363,12 @@ packages:
cpu: [arm]
os: [linux]
+ '@esbuild/linux-arm@0.21.5':
+ resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==}
+ engines: {node: '>=12'}
+ cpu: [arm]
+ os: [linux]
+
'@esbuild/linux-arm@0.24.0':
resolution: {integrity: sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==}
engines: {node: '>=18'}
@@ -3327,6 +3387,12 @@ packages:
cpu: [ia32]
os: [linux]
+ '@esbuild/linux-ia32@0.21.5':
+ resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==}
+ engines: {node: '>=12'}
+ cpu: [ia32]
+ os: [linux]
+
'@esbuild/linux-ia32@0.24.0':
resolution: {integrity: sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==}
engines: {node: '>=18'}
@@ -3345,6 +3411,12 @@ packages:
cpu: [loong64]
os: [linux]
+ '@esbuild/linux-loong64@0.21.5':
+ resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==}
+ engines: {node: '>=12'}
+ cpu: [loong64]
+ os: [linux]
+
'@esbuild/linux-loong64@0.24.0':
resolution: {integrity: sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==}
engines: {node: '>=18'}
@@ -3363,6 +3435,12 @@ packages:
cpu: [mips64el]
os: [linux]
+ '@esbuild/linux-mips64el@0.21.5':
+ resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==}
+ engines: {node: '>=12'}
+ cpu: [mips64el]
+ os: [linux]
+
'@esbuild/linux-mips64el@0.24.0':
resolution: {integrity: sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==}
engines: {node: '>=18'}
@@ -3381,6 +3459,12 @@ packages:
cpu: [ppc64]
os: [linux]
+ '@esbuild/linux-ppc64@0.21.5':
+ resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==}
+ engines: {node: '>=12'}
+ cpu: [ppc64]
+ os: [linux]
+
'@esbuild/linux-ppc64@0.24.0':
resolution: {integrity: sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==}
engines: {node: '>=18'}
@@ -3399,6 +3483,12 @@ packages:
cpu: [riscv64]
os: [linux]
+ '@esbuild/linux-riscv64@0.21.5':
+ resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==}
+ engines: {node: '>=12'}
+ cpu: [riscv64]
+ os: [linux]
+
'@esbuild/linux-riscv64@0.24.0':
resolution: {integrity: sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==}
engines: {node: '>=18'}
@@ -3417,6 +3507,12 @@ packages:
cpu: [s390x]
os: [linux]
+ '@esbuild/linux-s390x@0.21.5':
+ resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==}
+ engines: {node: '>=12'}
+ cpu: [s390x]
+ os: [linux]
+
'@esbuild/linux-s390x@0.24.0':
resolution: {integrity: sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==}
engines: {node: '>=18'}
@@ -3435,6 +3531,12 @@ packages:
cpu: [x64]
os: [linux]
+ '@esbuild/linux-x64@0.21.5':
+ resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [linux]
+
'@esbuild/linux-x64@0.24.0':
resolution: {integrity: sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==}
engines: {node: '>=18'}
@@ -3453,6 +3555,12 @@ packages:
cpu: [x64]
os: [netbsd]
+ '@esbuild/netbsd-x64@0.21.5':
+ resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [netbsd]
+
'@esbuild/netbsd-x64@0.24.0':
resolution: {integrity: sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==}
engines: {node: '>=18'}
@@ -3477,6 +3585,12 @@ packages:
cpu: [x64]
os: [openbsd]
+ '@esbuild/openbsd-x64@0.21.5':
+ resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [openbsd]
+
'@esbuild/openbsd-x64@0.24.0':
resolution: {integrity: sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==}
engines: {node: '>=18'}
@@ -3495,6 +3609,12 @@ packages:
cpu: [x64]
os: [sunos]
+ '@esbuild/sunos-x64@0.21.5':
+ resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [sunos]
+
'@esbuild/sunos-x64@0.24.0':
resolution: {integrity: sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==}
engines: {node: '>=18'}
@@ -3513,6 +3633,12 @@ packages:
cpu: [arm64]
os: [win32]
+ '@esbuild/win32-arm64@0.21.5':
+ resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [win32]
+
'@esbuild/win32-arm64@0.24.0':
resolution: {integrity: sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==}
engines: {node: '>=18'}
@@ -3531,6 +3657,12 @@ packages:
cpu: [ia32]
os: [win32]
+ '@esbuild/win32-ia32@0.21.5':
+ resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==}
+ engines: {node: '>=12'}
+ cpu: [ia32]
+ os: [win32]
+
'@esbuild/win32-ia32@0.24.0':
resolution: {integrity: sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==}
engines: {node: '>=18'}
@@ -3549,6 +3681,12 @@ packages:
cpu: [x64]
os: [win32]
+ '@esbuild/win32-x64@0.21.5':
+ resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [win32]
+
'@esbuild/win32-x64@0.24.0':
resolution: {integrity: sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==}
engines: {node: '>=18'}
@@ -5195,6 +5333,9 @@ packages:
'@tamagui/animate@1.112.12':
resolution: {integrity: sha512-9FAGebvmukqOnhRO3Nd5PyUuLVCJmvM9M+g7XwwVRh38E2HNsk2eTyxt2BwsvvYV6CGN25wmWmR1pQtJ8rbl3w==}
+ '@tamagui/animations-css@1.101.3':
+ resolution: {integrity: sha512-Rfidmg6xEuU6+uE+oCmCrZpbaxxzTsbWy6TjLsAmeBcahodICHVciu+vl2EjGpIbZ0zWXzutlhmH9Rlgss1sEw==}
+
'@tamagui/animations-css@1.112.12':
resolution: {integrity: sha512-0mAZbo2ZjpmK3394CwHfNA8bmBJXac32Ao5XmzOXWUJdJmibTFfgdsSyeo99zxj4UK6wKhailLz56P4nJelWhg==}
peerDependencies:
@@ -5221,12 +5362,19 @@ packages:
peerDependencies:
react: '*'
+ '@tamagui/babel-plugin-fully-specified@1.101.3':
+ resolution: {integrity: sha512-uYA6sp1kFb1a3QlN8CCn5ClSKd7rw2RzRXCctuLDeVS2bp/dnpgxMu05Sa7TKNGXsXTGP8KC6dfBTKo5lP1fQg==}
+
'@tamagui/babel-plugin-fully-specified@1.112.12':
resolution: {integrity: sha512-IeWEDDYcX0WR1FTCMfMLkpKSxWTy7UtOfNJLtiYdhYGS99ttYxU7VCBDEEkp1qY8TwD0wi4GVvqRY4t6o5GUZw==}
'@tamagui/babel-plugin@1.112.12':
resolution: {integrity: sha512-ZbJenBHgCb3Av3BA9HMYTx79+6xg/E4OzWXCZ71kD+ong2IKwkN6/U4P/DHnrq1lvUUkOGPfCFdhdEdLbvlozA==}
+ '@tamagui/build@1.101.3':
+ resolution: {integrity: sha512-fZZV6SuGXq2wA84XjgiJO/yr4TMETkdWWN4+gD0WZ/OG/Xgs8tLy/XLb7Z1TItFwODz3gTAJI6mtL+Q00WukUw==}
+ hasBin: true
+
'@tamagui/build@1.112.12':
resolution: {integrity: sha512-gVuZJl0rCGWzy0JLrdn5Niw4jqZk96bRAINVMOpmPNKCBXWKe/PmMxvB2dzOfM9rduxfNOlF/J/ggxhMMr5e+Q==}
hasBin: true
@@ -5251,6 +5399,9 @@ packages:
peerDependencies:
react: '*'
+ '@tamagui/cli-color@1.101.3':
+ resolution: {integrity: sha512-UiCDbBZGiq0tJ00m/hAZKQrg0k5WOtMpp3Ln8zsOqU7EC/r8bhELTH56GWemDE1ojw39YMo2t7B5vaJTYzpYZw==}
+
'@tamagui/cli-color@1.112.12':
resolution: {integrity: sha512-wTOUE9n6xKEJyWfj0asri0KGrYk9Yj2agbZhjG57KcR8RIbM02hoZ84Ljn3M43F8J8LxNRIti8s6aW6SnSJ1QA==}
@@ -5264,19 +5415,31 @@ packages:
peerDependencies:
react: '*'
+ '@tamagui/compose-refs@1.101.3':
+ resolution: {integrity: sha512-p4T4ea0qDzRN8n7+pgvn5XkGcFZf+gxS/JAq2DCUupJSjhzA3ZTdVCoMTzEfiZDTYHfx0mj12z7V4PU3WObXNg==}
+
'@tamagui/compose-refs@1.112.12':
resolution: {integrity: sha512-xwijG1j+IAn5RmhQ+8KoiJ9HtQQyKjsOLWGLBvQ5MdN9NHH9hTt83W4FbY4tTdWOgwQ9KywP9doMvzK69SgBMg==}
peerDependencies:
react: '*'
+ '@tamagui/config-default@1.101.3':
+ resolution: {integrity: sha512-VnKKZmdb8HFwhDRKVPHZggtWfjf/FQ5K3dbEnbu0BogvtU7V9OVGAJ/qYqoPD9Y+tfJrJ9keUcfpBt6io7dEWA==}
+
'@tamagui/config-default@1.112.12':
resolution: {integrity: sha512-j/wpsBsBF4hj9r778Kq7ANsgPh50bUVa7VLzWLe48FrV35J+MjafBGjwSPThLkFcPM8TRnHBFRPuKL4GAX4MuQ==}
+ '@tamagui/constants@1.101.3':
+ resolution: {integrity: sha512-nVppG0HaS7R0Tq3rAY0zVjcc5xszKcmCee4JRIJ8T6k4yPxW6Aqv8NJyAnS/5npET3ku72exVv9DeyU0WaJ07w==}
+
'@tamagui/constants@1.112.12':
resolution: {integrity: sha512-GkcqeF0m0ZHThPcAeDx9Z4qYGt7Cm1J72P8NQ7ax2WpilLlheGILRhrN9TUbKb0DXCz789GOjk+HnbksG1ihZw==}
peerDependencies:
react: '*'
+ '@tamagui/core@1.101.3':
+ resolution: {integrity: sha512-dhCguFJd/gfvULHBFh2OQPs8KVeMHbcBuY0WXeBIuU4h088QtNG5U0pgrwqHa05yuV4LirpIJc9y7j0OePqlBg==}
+
'@tamagui/core@1.112.12':
resolution: {integrity: sha512-s6GbHi0c2HgaFm/LOVuMIalb2ntXmSk9C+tsKFgwK6tg6k6w2qhWvrR05Gfm3IUN19Yb9X2VBqnXOzICwjaf+w==}
@@ -5285,9 +5448,15 @@ packages:
peerDependencies:
react: '*'
+ '@tamagui/create-theme@1.101.3':
+ resolution: {integrity: sha512-YFZUyAduxyrQ33wAewFT1cos5mgaRnCItetdHC5g+R8TpwEpSzfC+1e9t+ZBbWDP48usEp9euEnm3MbxpDqp6w==}
+
'@tamagui/create-theme@1.112.12':
resolution: {integrity: sha512-EVsV2UfihuGS8ThIQtUNAkft1+7nfABE8hHMiIm4djx2p/OOvJPy8u8oB0rUacygtFHQqTQ5uoVHuCxz8yPMfA==}
+ '@tamagui/cubic-bezier-animator@1.101.3':
+ resolution: {integrity: sha512-l7KuR1pOiKbe1N7cW08U7t0LxlAH0gA2f9XN8E5nMt3wftA7jLAE7FvbRPbaPXD4OPR2DwH/scWM8tY2i1SjYg==}
+
'@tamagui/cubic-bezier-animator@1.112.12':
resolution: {integrity: sha512-7M8iyfd5hFjwB4IlCjjuqP4rj6a61reLjaFuWLOCkEF+qOtlAhGPE8IJQgmlz8//RN/DrxsICXXvXuk9O5dmPg==}
@@ -5306,6 +5475,9 @@ packages:
peerDependencies:
react: '*'
+ '@tamagui/fake-react-native@1.101.3':
+ resolution: {integrity: sha512-Qsp5NBd4f/RN/qxPIRzKZJ5UWHWbIoVyzZVOdg9gkEYmIo6ZLIx0heRtIsuLY1bAu1u5SwB/lX8LnX3chzXaEA==}
+
'@tamagui/fake-react-native@1.112.12':
resolution: {integrity: sha512-ZsGGq6w74VgdBzgQ0m7YyBibDXPdxJK1I3Z28HoO7mtRhSMRXl/u0jE+r/KAkquMz78n5JP+ZLDa/jaKfKqbhA==}
@@ -5334,6 +5506,9 @@ packages:
peerDependencies:
react: '*'
+ '@tamagui/generate-themes@1.101.3':
+ resolution: {integrity: sha512-T+PXN2ZxBhmc3l2XO8hOrFA5ZBn9LfMWYV80srPR4W1LHd/Zc+wX3uwVVjbLPpUEvssUFfGpG6Y09542Wo9xWg==}
+
'@tamagui/generate-themes@1.112.12':
resolution: {integrity: sha512-hSVjTGQ9fq5HOwnMB1NAhvEnVgrigQiQstlxxRWmHf9bfPioTcvxkhKbfD6xQIg7BzbhGxf567aNr5wT9adkSg==}
@@ -5357,6 +5532,9 @@ packages:
peerDependencies:
react: '*'
+ '@tamagui/helpers-node@1.101.3':
+ resolution: {integrity: sha512-ZWXSeHHcxKkSb+IHweevnjCtH7r9jyDJ8meAPcdmkhUMuxtiz4+BZAHD/wOf1uHUTaSZF/o7mf1LylE6j4n+fA==}
+
'@tamagui/helpers-node@1.112.12':
resolution: {integrity: sha512-EABUdvWOe3LLnZKd++FrtNZy058GrTNhhs2GilswRIjwA2HLPDbcqGmdJwq5FWo7tBbvi5CW98fcVKINrI1uUg==}
@@ -5365,6 +5543,9 @@ packages:
peerDependencies:
react: '*'
+ '@tamagui/helpers@1.101.3':
+ resolution: {integrity: sha512-ertVEdjXUmkVRQA6/dHHG9P12ai7z6Upt+/N6Fguo84qcdlHVA2aSYshI3eOOatVjd4HOlNUpVHaqQ/JtuJboA==}
+
'@tamagui/helpers@1.112.12':
resolution: {integrity: sha512-OxnUIiaY27DPyZ0/N3RB4gqFGNr0yf3EUehjDLtTH9Hcpt1Z8ZVDXRrngdGd7p+jrktaXts5BWDelN3sXJiRWA==}
@@ -5389,6 +5570,9 @@ packages:
peerDependencies:
react: '*'
+ '@tamagui/normalize-css-color@1.101.3':
+ resolution: {integrity: sha512-F10Ao6btHQnBJb5yHtqbZYnWDXoWWMluusPNyS6WkOCTXky8FGA7P1rUkXG/CD6g8l1A8CZ7WmBBsX4lkC/ICg==}
+
'@tamagui/normalize-css-color@1.112.12':
resolution: {integrity: sha512-r8KU0h0bmad5i0fWx9pVwYLXLnYQ0OJp7C70KmJtP751cp/6y8BK2OZTGeJUq5DjyQhIf8M4foLvsM6ZarBe+g==}
@@ -5415,6 +5599,9 @@ packages:
peerDependencies:
react: '*'
+ '@tamagui/proxy-worm@1.101.3':
+ resolution: {integrity: sha512-9pGPhOTy2JFbKpJwcaBcTeCLJxhqGyXymcRlkwQKSBKlDRCEsC1R76b1IEBdxDMXzIXtI0xkRa2aNMwd3IoOLw==}
+
'@tamagui/proxy-worm@1.112.12':
resolution: {integrity: sha512-+uCBd4OraEmdS2wnYzc3XzZyBnuf8ewKplgXEHF3vpj8jGbRgPybFMTuFcdgZ5rLltYpnJg9JKAJ3ZPizQX5OA==}
@@ -5433,14 +5620,23 @@ packages:
peerDependencies:
react-native: '*'
+ '@tamagui/react-native-svg@1.101.3':
+ resolution: {integrity: sha512-/HOiFsCyEf79H1E+0BCte1x4godcGKJEKAv+crcoLKE4IWsbsgQuC8xsx+Dnv/cxuqKx0RqryP3yeA+CysVRiQ==}
+
'@tamagui/react-native-svg@1.112.12':
resolution: {integrity: sha512-ZLVdySFRrqwj4nqkxUSCC5IPCIVxRb9+JyZXdiVw444+bZ8ssfh5tu8iaPaltFkl2A41Xq69Y/217gi5Juw1sA==}
+ '@tamagui/react-native-use-pressable@1.101.3':
+ resolution: {integrity: sha512-nhz23ImLaAtmkG/5GvSsCCnpoS3uUS5iSQiU6kqY1AB5UOtIjZzS+613lB24ap5gXjagpUVmzrtJcB3Czx852Q==}
+
'@tamagui/react-native-use-pressable@1.112.12':
resolution: {integrity: sha512-JodPKfCanZR3hyn694rN22ExzPdINRJim63vZ5eKVnXnyTJ7ml/6JvzxlBgkozt3RBJjzUHm4Xha0JNwmG+law==}
peerDependencies:
react: '*'
+ '@tamagui/react-native-use-responder-events@1.101.3':
+ resolution: {integrity: sha512-iMDAGggb2DflmxptMYNwDIj6/0bfAuNtcnQXlB1Ar/C4xfG6Ubc6LhfUyyH++50PcFxYVpxN0KMqnsWSAptMdQ==}
+
'@tamagui/react-native-use-responder-events@1.112.12':
resolution: {integrity: sha512-vI4ORRAgfuiXTtSuEIbfcwsES9dy4Jqs9zdnD+vLII+5cdkjV9njM9AWS2kXnz+zvPdblXcIvaaH3hDOX14YeA==}
peerDependencies:
@@ -5489,9 +5685,15 @@ packages:
peerDependencies:
react: '*'
+ '@tamagui/shorthands@1.101.3':
+ resolution: {integrity: sha512-ADtfyBk+6JnS4xHQCWyEiVIn/jdtx4OZNxs5LLN4epUDYdTRem2w/xvV2uPPshMrqRRiMGYTYG4pPNTjBKRWlg==}
+
'@tamagui/shorthands@1.112.12':
resolution: {integrity: sha512-ei9uWmnszNFzi+9CBKx+v9pDe3XQuyweBQNolZxgAzRE/pLBkKMCfPZfK4xEaU8BgIwZBleg2iIf2LExH1IrTA==}
+ '@tamagui/simple-hash@1.101.3':
+ resolution: {integrity: sha512-yzRJXgzW1nxksCduzfZ03RjaFHZr3yzanaNUCUtQA6PFweIHnYw2UQTK26ZCWCSNjkrwVmL7RsB6h3WTjl/XUw==}
+
'@tamagui/simple-hash@1.112.12':
resolution: {integrity: sha512-G860Qc76HaxhPShNlcyifeMGJOqVD0brTQIQniv/+/8Zj12tSZezLvUVzt4XEWaGGt46VM8G4asM1ns0TEq3fg==}
@@ -5508,6 +5710,9 @@ packages:
'@tamagui/start-transition@1.112.12':
resolution: {integrity: sha512-idb/Rm9Oex/7JorjHVh6MT299ipqz0G1Gvgek5n8keX+VamaRPqmCSK4MakHIDIUV4h6+sHFbhfKTJ85WvlN0w==}
+ '@tamagui/static@1.101.3':
+ resolution: {integrity: sha512-8Z6tYK5uh3eKxv4p+Xu5HtmsY+PoLd9PF4EEZ/dfEtby22vCmVJClH+ukt1ykCdB0ysgw6vFqoZSptBIl9w1lg==}
+
'@tamagui/static@1.112.12':
resolution: {integrity: sha512-Vt8TV7CWbDypV3JklQ3TFacKkCIz7aOPq0A/nSs++4KM2/0YSoKth6s03o4uaWLunOcSqW0VdOx9FnMAEGtlTw==}
peerDependencies:
@@ -5533,6 +5738,9 @@ packages:
peerDependencies:
react: '*'
+ '@tamagui/theme-builder@1.101.3':
+ resolution: {integrity: sha512-PS9juD8yxO8r0h5A9F4+1ywmZ0G2iGIPLm6IbRj5z33cKL8Q4DfKWFdbo2RIwFoondkNG1dG5ObpHyYmkKvRqw==}
+
'@tamagui/theme-builder@1.112.12':
resolution: {integrity: sha512-EhYiUNGiRfqx9/URZlQRza/2t4S1dpKsjSthzA0arJhPv5H3wGmF1qw1XBS43wjTEy8X1hF+1fa+1zm8NLoYnA==}
@@ -5541,6 +5749,9 @@ packages:
peerDependencies:
react: '*'
+ '@tamagui/timer@1.101.3':
+ resolution: {integrity: sha512-chQEvSRnXHy9iJirxcf3D/z29b+YuMow2opyBZf8ce0IcCA8hOpQtqVmF6tvNcOSf2CE+UN+SLVglCWrnR0phg==}
+
'@tamagui/timer@1.112.12':
resolution: {integrity: sha512-/mH+iaPJfr91OShPL4cHnswbPv810+17JX/bLQmeeMo2Db4Nu3dMlf0CHdgxXHeL8jHdhWaC50U2Dj2ZmMxQqA==}
@@ -5554,6 +5765,9 @@ packages:
peerDependencies:
react: '*'
+ '@tamagui/types@1.101.3':
+ resolution: {integrity: sha512-CjPh6+Oyy7KVt5TRVxtqLrS/36GuvdrKYEHz7Zq1N4R8r3OwmjzUDiSCyJizLxD896DLiTMbDz9abAeDB5XWJA==}
+
'@tamagui/types@1.112.12':
resolution: {integrity: sha512-L/HgxcHwwnx0QV0f6aJFxIIUgRJ9WydDP8tBlvAropF0tinMSzqET8oMZ75/hVni/04vNrU1Mk+Ey12kERXvxg==}
@@ -5575,6 +5789,9 @@ packages:
peerDependencies:
react: '*'
+ '@tamagui/use-did-finish-ssr@1.101.3':
+ resolution: {integrity: sha512-5MOehyuYLeNwwHM973YNKbV39XE2/LFsUJmrR/EgXgI5fJZa452IdICkOrhVh6T86yohURh9NHAEG6oybcdPrA==}
+
'@tamagui/use-did-finish-ssr@1.112.12':
resolution: {integrity: sha512-Avi9xdYZ79rgN08O3znaZypVlSEMq1vq07qmmly7XH237Q5dIVstZfJtcrkc9uvw9/RpecrYne8UmMuy1sM1KQ==}
peerDependencies:
@@ -5588,11 +5805,17 @@ packages:
'@tamagui/use-escape-keydown@1.112.12':
resolution: {integrity: sha512-3WAa48LJts55TOgiHY/NmeOEq98MALzpjXsT96SLuSe4mtGtfhBwFca1EbwkA/ZHNMPt7lCMXufsxMqP+IW/lg==}
+ '@tamagui/use-event@1.101.3':
+ resolution: {integrity: sha512-ruB/ztONB7yxgYYIhOvWbWQeyjzFVcrgmgkwhzFn6UVbcw6Nq2SsFdeHAkzbF87yvp5Sd4ESVysRkO9VILP1Mw==}
+
'@tamagui/use-event@1.112.12':
resolution: {integrity: sha512-2Se3QquSRUcjomfVQHSrWFAEvBzSmSpNLiRIQIEFbevz1n7jE+u/AdKyQRH0KgU32urJ230Fyyij20conX8zjQ==}
peerDependencies:
react: '*'
+ '@tamagui/use-force-update@1.101.3':
+ resolution: {integrity: sha512-Smmd5wkzJ5noWuSRFuwxQcGnaPaDCInNcKeKLJDCWEj/9c0S7CFiOTW0109Ftv8dXAOmJp1t1pBWq8xk/KXy+A==}
+
'@tamagui/use-force-update@1.112.12':
resolution: {integrity: sha512-x4Vf5IOpNfeHjax/K7Ow7roMPAHcmw+K6EWdBG8uKpIVQjzQ3U+JlbAcmvzRWCNiwCqS8sd5k/GzttvRDgQtzA==}
peerDependencies:
@@ -5603,6 +5826,9 @@ packages:
peerDependencies:
react: '*'
+ '@tamagui/use-presence@1.101.3':
+ resolution: {integrity: sha512-o1LxS/6J/vseO1fVh+vbTe6Y8iEXGHNnnGRQL5z0XfLacnL8936OaOnc0PvEKENvZE/7Tnxgo7a/QJpLvIDJsA==}
+
'@tamagui/use-presence@1.112.12':
resolution: {integrity: sha512-qpU6AvQMLubb9xqY6zKr0Ihk6PeJ3vxRjivoXCQL/JWBMe64TM9Tk1cYd7QkyuO3wN1ydLLgpSl7Dn3ANAdYBg==}
peerDependencies:
@@ -5621,9 +5847,15 @@ packages:
peerDependencies:
react: '*'
+ '@tamagui/vite-plugin@1.101.3':
+ resolution: {integrity: sha512-+FPYUuJyUEn4JFBcqEXYaeQhzmQqKfcIUzyyuEgXvy8KlCkT8iRTtu11tyAAqpPaivIous0aifQHRVwSBn47jA==}
+
'@tamagui/vite-plugin@1.112.12':
resolution: {integrity: sha512-iMIPmfcrJALKIQ9E5E8+RuE3d9+HKY9M0QZSmLjv+u7gdFUrnSYIOsaVfPFNPva5yvvKcnWOoIdnrRvpom/93A==}
+ '@tamagui/web@1.101.3':
+ resolution: {integrity: sha512-JQqyOxbDyDsQ+7ddsTI6zFGmhFKK2SOlTiFo4jXTGvPiooVSxZxkXufvXbsLp887VrdhnhOWZruFYGoCkorv2A==}
+
'@tamagui/web@1.112.12':
resolution: {integrity: sha512-6JqU0gyogmMX3ofPALyeVKAze1bshXm+1DSJ2PYJR8hNR5WQhikN0XBX1X65Iq9Fr3wcCg3ZKGKy/5X3H6enCg==}
@@ -8012,6 +8244,11 @@ packages:
engines: {node: '>=12'}
hasBin: true
+ esbuild@0.21.5:
+ resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==}
+ engines: {node: '>=12'}
+ hasBin: true
+
esbuild@0.24.0:
resolution: {integrity: sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==}
engines: {node: '>=18'}
@@ -11345,6 +11582,14 @@ packages:
peerDependencies:
react-native: '*'
+ react-native-web-internals@1.101.3:
+ resolution: {integrity: sha512-xjisf0UVxkxiZQwnnsYlo3ms11qHoo7TIGWnH78exkfsgfFrAOzVodH/Mu0p5Yeofs7KQ9YFUhj31/fuaKF4yA==}
+
+ react-native-web-lite@1.101.3:
+ resolution: {integrity: sha512-6MD+R3M+UmlopPM6/QEMHPflg6gfiS8Kssr36GNxADwCykvr3/e2Eo6Bv89yarClL1LWG5bBix53wtgu9M4//Q==}
+ peerDependencies:
+ react: '*'
+
react-native-web@0.19.12:
resolution: {integrity: sha512-o2T0oztoVDQjztt4YksO9S1XRjoH/AqcSvifgWLrPJgGVbMWsfhILgl6lfUdEamVZzZSVV/2gqDVMAk/qq7mZw==}
peerDependencies:
@@ -14319,7 +14564,7 @@ snapshots:
'@babel/helper-create-regexp-features-plugin@7.22.15(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-annotate-as-pure': 7.22.5
+ '@babel/helper-annotate-as-pure': 7.24.7
regexpu-core: 5.3.2
semver: 6.3.1
@@ -14401,7 +14646,7 @@ snapshots:
'@babel/helper-remap-async-to-generator@7.22.20(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-annotate-as-pure': 7.22.5
+ '@babel/helper-annotate-as-pure': 7.24.7
'@babel/helper-environment-visitor': 7.22.20
'@babel/helper-wrap-function': 7.22.20
@@ -14490,12 +14735,12 @@ snapshots:
'@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.23.3(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.23.3(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/helper-skip-transparent-expression-wrappers': 7.22.5
'@babel/plugin-transform-optional-chaining': 7.23.4(@babel/core@7.25.2)
@@ -14503,13 +14748,13 @@ snapshots:
dependencies:
'@babel/core': 7.25.2
'@babel/helper-environment-visitor': 7.22.20
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-proposal-async-generator-functions@7.20.7(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
'@babel/helper-environment-visitor': 7.22.20
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.25.2)
'@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.25.2)
@@ -14517,7 +14762,7 @@ snapshots:
dependencies:
'@babel/core': 7.25.2
'@babel/helper-create-class-features-plugin': 7.23.10(@babel/core@7.25.2)
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-proposal-decorators@7.23.9(@babel/core@7.25.2)':
dependencies:
@@ -14529,7 +14774,7 @@ snapshots:
'@babel/plugin-proposal-export-default-from@7.23.3(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-syntax-export-default-from': 7.23.3(@babel/core@7.25.2)
'@babel/plugin-proposal-export-namespace-from@7.18.9(@babel/core@7.25.2)':
@@ -14541,13 +14786,13 @@ snapshots:
'@babel/plugin-proposal-nullish-coalescing-operator@7.18.6(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.25.2)
'@babel/plugin-proposal-numeric-separator@7.18.6(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.25.2)
'@babel/plugin-proposal-object-rest-spread@7.20.7(@babel/core@7.25.2)':
@@ -14555,20 +14800,20 @@ snapshots:
'@babel/compat-data': 7.25.2
'@babel/core': 7.25.2
'@babel/helper-compilation-targets': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.25.2)
'@babel/plugin-transform-parameters': 7.23.3(@babel/core@7.25.2)
'@babel/plugin-proposal-optional-catch-binding@7.18.6(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.25.2)
'@babel/plugin-proposal-optional-chaining@7.21.0(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/helper-skip-transparent-expression-wrappers': 7.22.5
'@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.25.2)
@@ -14579,7 +14824,7 @@ snapshots:
'@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.25.2)':
dependencies:
@@ -14589,27 +14834,27 @@ snapshots:
'@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-syntax-decorators@7.23.3(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-syntax-export-default-from@7.23.3(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.25.2)':
dependencies:
@@ -14619,27 +14864,27 @@ snapshots:
'@babel/plugin-syntax-flow@7.23.3(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-syntax-import-assertions@7.23.3(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-syntax-import-attributes@7.23.3(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-syntax-jsx@7.23.3(@babel/core@7.25.2)':
dependencies:
@@ -14654,7 +14899,7 @@ snapshots:
'@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.25.2)':
dependencies:
@@ -14664,17 +14909,17 @@ snapshots:
'@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.25.2)':
dependencies:
@@ -14684,12 +14929,12 @@ snapshots:
'@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-syntax-typescript@7.23.3(@babel/core@7.25.2)':
dependencies:
@@ -14700,7 +14945,7 @@ snapshots:
dependencies:
'@babel/core': 7.25.2
'@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.25.2)
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-transform-arrow-functions@7.23.3(@babel/core@7.25.2)':
dependencies:
@@ -14711,7 +14956,7 @@ snapshots:
dependencies:
'@babel/core': 7.25.2
'@babel/helper-environment-visitor': 7.22.20
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.25.2)
'@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.25.2)
@@ -14727,24 +14972,24 @@ snapshots:
'@babel/plugin-transform-block-scoped-functions@7.23.3(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-transform-block-scoping@7.23.4(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-transform-class-properties@7.23.3(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
'@babel/helper-create-class-features-plugin': 7.23.10(@babel/core@7.25.2)
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-transform-class-static-block@7.23.4(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
'@babel/helper-create-class-features-plugin': 7.23.10(@babel/core@7.25.2)
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.25.2)
'@babel/plugin-transform-classes@7.23.8(@babel/core@7.25.2)':
@@ -14754,7 +14999,7 @@ snapshots:
'@babel/helper-compilation-targets': 7.25.2
'@babel/helper-environment-visitor': 7.22.20
'@babel/helper-function-name': 7.23.0
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/helper-replace-supers': 7.22.20(@babel/core@7.25.2)
'@babel/helper-split-export-declaration': 7.22.6
globals: 11.12.0
@@ -14762,36 +15007,36 @@ snapshots:
'@babel/plugin-transform-computed-properties@7.23.3(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/template': 7.25.0
'@babel/plugin-transform-destructuring@7.23.3(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-transform-dotall-regex@7.23.3(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
'@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.25.2)
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-transform-duplicate-keys@7.23.3(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-transform-dynamic-import@7.23.4(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.25.2)
'@babel/plugin-transform-exponentiation-operator@7.23.3(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
'@babel/helper-builder-binary-assignment-operator-visitor': 7.22.15
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-transform-export-namespace-from@7.23.4(@babel/core@7.25.2)':
dependencies:
@@ -14802,13 +15047,13 @@ snapshots:
'@babel/plugin-transform-flow-strip-types@7.23.3(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-syntax-flow': 7.23.3(@babel/core@7.25.2)
'@babel/plugin-transform-for-of@7.23.6(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/helper-skip-transparent-expression-wrappers': 7.22.5
'@babel/plugin-transform-function-name@7.23.3(@babel/core@7.25.2)':
@@ -14816,35 +15061,35 @@ snapshots:
'@babel/core': 7.25.2
'@babel/helper-compilation-targets': 7.25.2
'@babel/helper-function-name': 7.23.0
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-transform-json-strings@7.23.4(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.25.2)
'@babel/plugin-transform-literals@7.23.3(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-transform-logical-assignment-operators@7.23.4(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.25.2)
'@babel/plugin-transform-member-expression-literals@7.23.3(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-transform-modules-amd@7.23.3(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
'@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2)
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
transitivePeerDependencies:
- supports-color
@@ -14862,7 +15107,7 @@ snapshots:
'@babel/core': 7.25.2
'@babel/helper-hoist-variables': 7.22.5
'@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2)
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/helper-validator-identifier': 7.22.20
transitivePeerDependencies:
- supports-color
@@ -14871,7 +15116,7 @@ snapshots:
dependencies:
'@babel/core': 7.25.2
'@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2)
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
transitivePeerDependencies:
- supports-color
@@ -14879,12 +15124,12 @@ snapshots:
dependencies:
'@babel/core': 7.25.2
'@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.25.2)
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-transform-new-target@7.23.3(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-transform-nullish-coalescing-operator@7.23.4(@babel/core@7.25.2)':
dependencies:
@@ -14895,7 +15140,7 @@ snapshots:
'@babel/plugin-transform-numeric-separator@7.23.4(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.25.2)
'@babel/plugin-transform-object-rest-spread@7.23.4(@babel/core@7.25.2)':
@@ -14910,13 +15155,13 @@ snapshots:
'@babel/plugin-transform-object-super@7.23.3(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/helper-replace-supers': 7.22.20(@babel/core@7.25.2)
'@babel/plugin-transform-optional-catch-binding@7.23.4(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.25.2)
'@babel/plugin-transform-optional-chaining@7.23.4(@babel/core@7.25.2)':
@@ -14935,30 +15180,32 @@ snapshots:
dependencies:
'@babel/core': 7.25.2
'@babel/helper-create-class-features-plugin': 7.23.10(@babel/core@7.25.2)
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-transform-private-property-in-object@7.23.4(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
'@babel/helper-annotate-as-pure': 7.22.5
'@babel/helper-create-class-features-plugin': 7.23.10(@babel/core@7.25.2)
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.25.2)
'@babel/plugin-transform-property-literals@7.23.3(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-transform-react-display-name@7.23.3(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-transform-react-jsx-development@7.22.5(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/plugin-transform-react-jsx': 7.23.4(@babel/core@7.25.2)
+ '@babel/plugin-transform-react-jsx': 7.25.2(@babel/core@7.25.2)
+ transitivePeerDependencies:
+ - supports-color
'@babel/plugin-transform-react-jsx-self@7.23.3(@babel/core@7.23.7)':
dependencies:
@@ -14985,9 +15232,9 @@ snapshots:
'@babel/core': 7.25.2
'@babel/helper-annotate-as-pure': 7.22.5
'@babel/helper-module-imports': 7.22.15
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.25.2)
- '@babel/types': 7.25.2
+ '@babel/types': 7.25.6
'@babel/plugin-transform-react-jsx@7.25.2(@babel/core@7.25.2)':
dependencies:
@@ -15004,24 +15251,24 @@ snapshots:
dependencies:
'@babel/core': 7.25.2
'@babel/helper-annotate-as-pure': 7.22.5
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-transform-regenerator@7.23.3(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
regenerator-transform: 0.15.2
'@babel/plugin-transform-reserved-words@7.23.3(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-transform-runtime@7.23.9(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
'@babel/helper-module-imports': 7.24.7
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
babel-plugin-polyfill-corejs2: 0.4.8(@babel/core@7.25.2)
babel-plugin-polyfill-corejs3: 0.9.0(@babel/core@7.25.2)
babel-plugin-polyfill-regenerator: 0.5.5(@babel/core@7.25.2)
@@ -15037,13 +15284,13 @@ snapshots:
'@babel/plugin-transform-spread@7.23.3(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/helper-skip-transparent-expression-wrappers': 7.22.5
'@babel/plugin-transform-sticky-regex@7.23.3(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-transform-template-literals@7.23.3(@babel/core@7.25.2)':
dependencies:
@@ -15053,7 +15300,7 @@ snapshots:
'@babel/plugin-transform-typeof-symbol@7.23.3(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-transform-typescript@7.23.6(@babel/core@7.25.2)':
dependencies:
@@ -15066,25 +15313,25 @@ snapshots:
'@babel/plugin-transform-unicode-escapes@7.23.3(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-transform-unicode-property-regex@7.23.3(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
'@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.25.2)
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-transform-unicode-regex@7.23.3(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
'@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.25.2)
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/plugin-transform-unicode-sets-regex@7.23.3(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
'@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.25.2)
- '@babel/helper-plugin-utils': 7.22.5
+ '@babel/helper-plugin-utils': 7.24.8
'@babel/preset-env@7.23.7(@babel/core@7.25.2)':
dependencies:
@@ -15182,8 +15429,8 @@ snapshots:
'@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.22.5
- '@babel/types': 7.25.2
+ '@babel/helper-plugin-utils': 7.24.8
+ '@babel/types': 7.25.6
esutils: 2.0.3
'@babel/preset-react@7.23.3(@babel/core@7.25.2)':
@@ -15195,6 +15442,8 @@ snapshots:
'@babel/plugin-transform-react-jsx': 7.23.4(@babel/core@7.25.2)
'@babel/plugin-transform-react-jsx-development': 7.22.5(@babel/core@7.25.2)
'@babel/plugin-transform-react-pure-annotations': 7.23.3(@babel/core@7.25.2)
+ transitivePeerDependencies:
+ - supports-color
'@babel/preset-typescript@7.23.3(@babel/core@7.25.2)':
dependencies:
@@ -15412,6 +15661,9 @@ snapshots:
'@esbuild/aix-ppc64@0.19.12':
optional: true
+ '@esbuild/aix-ppc64@0.21.5':
+ optional: true
+
'@esbuild/aix-ppc64@0.24.0':
optional: true
@@ -15421,6 +15673,9 @@ snapshots:
'@esbuild/android-arm64@0.19.12':
optional: true
+ '@esbuild/android-arm64@0.21.5':
+ optional: true
+
'@esbuild/android-arm64@0.24.0':
optional: true
@@ -15430,6 +15685,9 @@ snapshots:
'@esbuild/android-arm@0.19.12':
optional: true
+ '@esbuild/android-arm@0.21.5':
+ optional: true
+
'@esbuild/android-arm@0.24.0':
optional: true
@@ -15439,6 +15697,9 @@ snapshots:
'@esbuild/android-x64@0.19.12':
optional: true
+ '@esbuild/android-x64@0.21.5':
+ optional: true
+
'@esbuild/android-x64@0.24.0':
optional: true
@@ -15448,6 +15709,9 @@ snapshots:
'@esbuild/darwin-arm64@0.19.12':
optional: true
+ '@esbuild/darwin-arm64@0.21.5':
+ optional: true
+
'@esbuild/darwin-arm64@0.24.0':
optional: true
@@ -15457,6 +15721,9 @@ snapshots:
'@esbuild/darwin-x64@0.19.12':
optional: true
+ '@esbuild/darwin-x64@0.21.5':
+ optional: true
+
'@esbuild/darwin-x64@0.24.0':
optional: true
@@ -15466,6 +15733,9 @@ snapshots:
'@esbuild/freebsd-arm64@0.19.12':
optional: true
+ '@esbuild/freebsd-arm64@0.21.5':
+ optional: true
+
'@esbuild/freebsd-arm64@0.24.0':
optional: true
@@ -15475,6 +15745,9 @@ snapshots:
'@esbuild/freebsd-x64@0.19.12':
optional: true
+ '@esbuild/freebsd-x64@0.21.5':
+ optional: true
+
'@esbuild/freebsd-x64@0.24.0':
optional: true
@@ -15484,6 +15757,9 @@ snapshots:
'@esbuild/linux-arm64@0.19.12':
optional: true
+ '@esbuild/linux-arm64@0.21.5':
+ optional: true
+
'@esbuild/linux-arm64@0.24.0':
optional: true
@@ -15493,6 +15769,9 @@ snapshots:
'@esbuild/linux-arm@0.19.12':
optional: true
+ '@esbuild/linux-arm@0.21.5':
+ optional: true
+
'@esbuild/linux-arm@0.24.0':
optional: true
@@ -15502,6 +15781,9 @@ snapshots:
'@esbuild/linux-ia32@0.19.12':
optional: true
+ '@esbuild/linux-ia32@0.21.5':
+ optional: true
+
'@esbuild/linux-ia32@0.24.0':
optional: true
@@ -15511,6 +15793,9 @@ snapshots:
'@esbuild/linux-loong64@0.19.12':
optional: true
+ '@esbuild/linux-loong64@0.21.5':
+ optional: true
+
'@esbuild/linux-loong64@0.24.0':
optional: true
@@ -15520,6 +15805,9 @@ snapshots:
'@esbuild/linux-mips64el@0.19.12':
optional: true
+ '@esbuild/linux-mips64el@0.21.5':
+ optional: true
+
'@esbuild/linux-mips64el@0.24.0':
optional: true
@@ -15529,6 +15817,9 @@ snapshots:
'@esbuild/linux-ppc64@0.19.12':
optional: true
+ '@esbuild/linux-ppc64@0.21.5':
+ optional: true
+
'@esbuild/linux-ppc64@0.24.0':
optional: true
@@ -15538,6 +15829,9 @@ snapshots:
'@esbuild/linux-riscv64@0.19.12':
optional: true
+ '@esbuild/linux-riscv64@0.21.5':
+ optional: true
+
'@esbuild/linux-riscv64@0.24.0':
optional: true
@@ -15547,6 +15841,9 @@ snapshots:
'@esbuild/linux-s390x@0.19.12':
optional: true
+ '@esbuild/linux-s390x@0.21.5':
+ optional: true
+
'@esbuild/linux-s390x@0.24.0':
optional: true
@@ -15556,6 +15853,9 @@ snapshots:
'@esbuild/linux-x64@0.19.12':
optional: true
+ '@esbuild/linux-x64@0.21.5':
+ optional: true
+
'@esbuild/linux-x64@0.24.0':
optional: true
@@ -15565,6 +15865,9 @@ snapshots:
'@esbuild/netbsd-x64@0.19.12':
optional: true
+ '@esbuild/netbsd-x64@0.21.5':
+ optional: true
+
'@esbuild/netbsd-x64@0.24.0':
optional: true
@@ -15577,6 +15880,9 @@ snapshots:
'@esbuild/openbsd-x64@0.19.12':
optional: true
+ '@esbuild/openbsd-x64@0.21.5':
+ optional: true
+
'@esbuild/openbsd-x64@0.24.0':
optional: true
@@ -15586,6 +15892,9 @@ snapshots:
'@esbuild/sunos-x64@0.19.12':
optional: true
+ '@esbuild/sunos-x64@0.21.5':
+ optional: true
+
'@esbuild/sunos-x64@0.24.0':
optional: true
@@ -15595,6 +15904,9 @@ snapshots:
'@esbuild/win32-arm64@0.19.12':
optional: true
+ '@esbuild/win32-arm64@0.21.5':
+ optional: true
+
'@esbuild/win32-arm64@0.24.0':
optional: true
@@ -15604,6 +15916,9 @@ snapshots:
'@esbuild/win32-ia32@0.19.12':
optional: true
+ '@esbuild/win32-ia32@0.21.5':
+ optional: true
+
'@esbuild/win32-ia32@0.24.0':
optional: true
@@ -15613,6 +15928,9 @@ snapshots:
'@esbuild/win32-x64@0.19.12':
optional: true
+ '@esbuild/win32-x64@0.21.5':
+ optional: true
+
'@esbuild/win32-x64@0.24.0':
optional: true
@@ -17751,6 +18069,14 @@ snapshots:
picomatch: 2.3.1
rollup: 2.79.1
+ '@rollup/pluginutils@5.1.0(rollup@2.79.1)':
+ dependencies:
+ '@types/estree': 1.0.5
+ estree-walker: 2.0.2
+ picomatch: 2.3.1
+ optionalDependencies:
+ rollup: 2.79.1
+
'@rollup/pluginutils@5.1.0(rollup@4.13.0)':
dependencies:
'@types/estree': 1.0.5
@@ -18064,6 +18390,13 @@ snapshots:
transitivePeerDependencies:
- react
+ '@tamagui/animations-css@1.101.3':
+ dependencies:
+ '@tamagui/constants': 1.101.3
+ '@tamagui/cubic-bezier-animator': 1.101.3
+ '@tamagui/use-presence': 1.101.3
+ '@tamagui/web': 1.101.3
+
'@tamagui/animations-css@1.112.12(react@18.2.0)':
dependencies:
'@tamagui/constants': 1.112.12(react@18.2.0)
@@ -18100,6 +18433,12 @@ snapshots:
'@tamagui/text': 1.112.12(react@18.2.0)
react: 18.2.0
+ '@tamagui/babel-plugin-fully-specified@1.101.3':
+ dependencies:
+ '@babel/core': 7.25.2
+ transitivePeerDependencies:
+ - supports-color
+
'@tamagui/babel-plugin-fully-specified@1.112.12':
dependencies:
'@babel/core': 7.25.2
@@ -18119,6 +18458,24 @@ snapshots:
- react
- supports-color
+ '@tamagui/build@1.101.3':
+ dependencies:
+ '@babel/core': 7.25.2
+ '@tamagui/babel-plugin-fully-specified': 1.101.3
+ '@types/fs-extra': 9.0.13
+ babel-plugin-fully-specified: 1.3.0(@babel/core@7.25.2)
+ chokidar: 3.5.3
+ esbuild: 0.21.5
+ esbuild-plugin-es5: 2.1.1(esbuild@0.21.5)
+ esbuild-register: 3.6.0(esbuild@0.21.5)
+ execa: 5.1.1
+ fast-glob: 3.3.2
+ fs-extra: 11.2.0
+ get-tsconfig: 4.7.2
+ lodash.debounce: 4.0.8
+ transitivePeerDependencies:
+ - supports-color
+
'@tamagui/build@1.112.12(@swc/helpers@0.5.13)':
dependencies:
'@babel/core': 7.25.2
@@ -18192,6 +18549,8 @@ snapshots:
transitivePeerDependencies:
- react-native
+ '@tamagui/cli-color@1.101.3': {}
+
'@tamagui/cli-color@1.112.12': {}
'@tamagui/collapsible@1.112.12(react@18.2.0)':
@@ -18217,10 +18576,18 @@ snapshots:
'@tamagui/use-controllable-state': 1.112.12(react@18.2.0)
react: 18.2.0
+ '@tamagui/compose-refs@1.101.3': {}
+
'@tamagui/compose-refs@1.112.12(react@18.2.0)':
dependencies:
react: 18.2.0
+ '@tamagui/config-default@1.101.3':
+ dependencies:
+ '@tamagui/animations-css': 1.101.3
+ '@tamagui/core': 1.101.3
+ '@tamagui/shorthands': 1.101.3
+
'@tamagui/config-default@1.112.12(react@18.2.0)':
dependencies:
'@tamagui/animations-css': 1.112.12(react@18.2.0)
@@ -18229,10 +18596,19 @@ snapshots:
transitivePeerDependencies:
- react
+ '@tamagui/constants@1.101.3': {}
+
'@tamagui/constants@1.112.12(react@18.2.0)':
dependencies:
react: 18.2.0
+ '@tamagui/core@1.101.3':
+ dependencies:
+ '@tamagui/react-native-use-pressable': 1.101.3
+ '@tamagui/react-native-use-responder-events': 1.101.3
+ '@tamagui/use-event': 1.101.3
+ '@tamagui/web': 1.101.3
+
'@tamagui/core@1.112.12(react@18.2.0)':
dependencies:
'@tamagui/react-native-use-pressable': 1.112.12(react@18.2.0)
@@ -18246,12 +18622,18 @@ snapshots:
dependencies:
react: 18.2.0
+ '@tamagui/create-theme@1.101.3':
+ dependencies:
+ '@tamagui/web': 1.101.3
+
'@tamagui/create-theme@1.112.12(react@18.2.0)':
dependencies:
'@tamagui/web': 1.112.12(react@18.2.0)
transitivePeerDependencies:
- react
+ '@tamagui/cubic-bezier-animator@1.101.3': {}
+
'@tamagui/cubic-bezier-animator@1.112.12': {}
'@tamagui/dialog@1.112.12(@types/react@18.2.55)(react-dom@18.2.0(react@18.2.0))(react-native@0.73.9(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2))(encoding@0.1.13)(react@18.2.0))(react@18.2.0)':
@@ -18294,6 +18676,8 @@ snapshots:
'@tamagui/core': 1.112.12(react@18.2.0)
react: 18.2.0
+ '@tamagui/fake-react-native@1.101.3': {}
+
'@tamagui/fake-react-native@1.112.12': {}
'@tamagui/floating@1.112.12(react-dom@18.2.0(react@18.2.0))(react-native@0.73.9(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2))(encoding@0.1.13)(react@18.2.0))(react@18.2.0)':
@@ -18335,6 +18719,17 @@ snapshots:
'@tamagui/text': 1.112.12(react@18.2.0)
react: 18.2.0
+ '@tamagui/generate-themes@1.101.3(esbuild@0.21.5)':
+ dependencies:
+ '@tamagui/create-theme': 1.101.3
+ '@tamagui/theme-builder': 1.101.3
+ '@tamagui/types': 1.101.3
+ esbuild-register: 3.6.0(esbuild@0.21.5)
+ fs-extra: 11.2.0
+ transitivePeerDependencies:
+ - esbuild
+ - supports-color
+
'@tamagui/generate-themes@1.112.12(esbuild@0.24.0)(react@18.2.0)':
dependencies:
'@tamagui/create-theme': 1.112.12(react@18.2.0)
@@ -18372,6 +18767,10 @@ snapshots:
'@tamagui/use-controllable-state': 1.112.12(react@18.2.0)
react: 18.2.0
+ '@tamagui/helpers-node@1.101.3':
+ dependencies:
+ '@tamagui/types': 1.101.3
+
'@tamagui/helpers-node@1.112.12':
dependencies:
'@tamagui/types': 1.112.12
@@ -18382,6 +18781,11 @@ snapshots:
'@tamagui/web': 1.112.12(react@18.2.0)
react: 18.2.0
+ '@tamagui/helpers@1.101.3':
+ dependencies:
+ '@tamagui/constants': 1.101.3
+ '@tamagui/simple-hash': 1.101.3
+
'@tamagui/helpers@1.112.12(react@18.2.0)':
dependencies:
'@tamagui/constants': 1.112.12(react@18.2.0)
@@ -18426,6 +18830,10 @@ snapshots:
'@tamagui/web': 1.112.12(react@18.2.0)
react: 18.2.0
+ '@tamagui/normalize-css-color@1.101.3':
+ dependencies:
+ '@react-native/normalize-color': 2.1.0
+
'@tamagui/normalize-css-color@1.112.12':
dependencies:
'@react-native/normalize-color': 2.1.0
@@ -18495,6 +18903,8 @@ snapshots:
'@tamagui/stacks': 1.112.12(react@18.2.0)
react: 18.2.0
+ '@tamagui/proxy-worm@1.101.3': {}
+
'@tamagui/proxy-worm@1.112.12': {}
'@tamagui/radio-group@1.112.12(react-native@0.73.9(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2))(encoding@0.1.13)(react@18.2.0))(react@18.2.0)':
@@ -18537,12 +18947,18 @@ snapshots:
transitivePeerDependencies:
- react
+ '@tamagui/react-native-svg@1.101.3': {}
+
'@tamagui/react-native-svg@1.112.12': {}
+ '@tamagui/react-native-use-pressable@1.101.3': {}
+
'@tamagui/react-native-use-pressable@1.112.12(react@18.2.0)':
dependencies:
react: 18.2.0
+ '@tamagui/react-native-use-responder-events@1.101.3': {}
+
'@tamagui/react-native-use-responder-events@1.112.12(react@18.2.0)':
dependencies:
react: 18.2.0
@@ -18656,8 +19072,12 @@ snapshots:
transitivePeerDependencies:
- '@types/react'
+ '@tamagui/shorthands@1.101.3': {}
+
'@tamagui/shorthands@1.112.12': {}
+ '@tamagui/simple-hash@1.101.3': {}
+
'@tamagui/simple-hash@1.112.12': {}
'@tamagui/slider@1.112.12(react@18.2.0)':
@@ -18683,6 +19103,46 @@ snapshots:
dependencies:
react: 18.2.0
+ '@tamagui/static@1.101.3(encoding@0.1.13)(react@18.2.0)':
+ dependencies:
+ '@babel/core': 7.25.2
+ '@babel/generator': 7.25.6
+ '@babel/helper-plugin-utils': 7.24.8
+ '@babel/parser': 7.25.6
+ '@babel/plugin-transform-react-jsx': 7.25.2(@babel/core@7.25.2)
+ '@babel/runtime': 7.25.6
+ '@babel/traverse': 7.25.6
+ '@babel/types': 7.25.6
+ '@tamagui/build': 1.101.3
+ '@tamagui/cli-color': 1.101.3
+ '@tamagui/config-default': 1.101.3
+ '@tamagui/core': 1.101.3
+ '@tamagui/fake-react-native': 1.101.3
+ '@tamagui/generate-themes': 1.101.3(esbuild@0.21.5)
+ '@tamagui/helpers': 1.101.3
+ '@tamagui/helpers-node': 1.101.3
+ '@tamagui/proxy-worm': 1.101.3
+ '@tamagui/shorthands': 1.101.3
+ '@tamagui/types': 1.101.3
+ babel-literal-to-ast: 2.1.0(@babel/core@7.25.2)
+ browserslist: 4.23.3
+ check-dependency-version-consistency: 4.1.0
+ esbuild: 0.21.5
+ esbuild-register: 3.6.0(esbuild@0.21.5)
+ find-cache-dir: 3.3.2
+ find-root: 1.1.0
+ fs-extra: 11.2.0
+ invariant: 2.2.4
+ lodash: 4.17.21
+ react-dom: 18.2.0(react@18.2.0)
+ react-native-web: 0.19.12(encoding@0.1.13)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
+ react-native-web-internals: 1.101.3
+ react-native-web-lite: 1.101.3(react@18.2.0)
+ transitivePeerDependencies:
+ - encoding
+ - react
+ - supports-color
+
'@tamagui/static@1.112.12(@swc/helpers@0.5.13)(encoding@0.1.13)(react@18.2.0)':
dependencies:
'@babel/core': 7.25.2
@@ -18774,6 +19234,11 @@ snapshots:
'@tamagui/web': 1.112.12(react@18.2.0)
react: 18.2.0
+ '@tamagui/theme-builder@1.101.3':
+ dependencies:
+ '@tamagui/create-theme': 1.101.3
+ color2k: 2.0.3
+
'@tamagui/theme-builder@1.112.12(react@18.2.0)':
dependencies:
'@tamagui/create-theme': 1.112.12(react@18.2.0)
@@ -18787,6 +19252,8 @@ snapshots:
'@tamagui/web': 1.112.12(react@18.2.0)
react: 18.2.0
+ '@tamagui/timer@1.101.3': {}
+
'@tamagui/timer@1.112.12': {}
'@tamagui/toggle-group@1.112.12(react@18.2.0)':
@@ -18827,6 +19294,8 @@ snapshots:
- react-dom
- react-native
+ '@tamagui/types@1.101.3': {}
+
'@tamagui/types@1.112.12': {}
'@tamagui/use-callback-ref@1.112.12': {}
@@ -18845,6 +19314,10 @@ snapshots:
dependencies:
react: 18.2.0
+ '@tamagui/use-did-finish-ssr@1.101.3':
+ dependencies:
+ '@tamagui/constants': 1.101.3
+
'@tamagui/use-did-finish-ssr@1.112.12(react@18.2.0)':
dependencies:
react: 18.2.0
@@ -18857,11 +19330,17 @@ snapshots:
dependencies:
'@tamagui/use-callback-ref': 1.112.12
+ '@tamagui/use-event@1.101.3':
+ dependencies:
+ '@tamagui/constants': 1.101.3
+
'@tamagui/use-event@1.112.12(react@18.2.0)':
dependencies:
'@tamagui/constants': 1.112.12(react@18.2.0)
react: 18.2.0
+ '@tamagui/use-force-update@1.101.3': {}
+
'@tamagui/use-force-update@1.112.12(react@18.2.0)':
dependencies:
react: 18.2.0
@@ -18870,6 +19349,10 @@ snapshots:
dependencies:
react: 18.2.0
+ '@tamagui/use-presence@1.101.3':
+ dependencies:
+ '@tamagui/web': 1.101.3
+
'@tamagui/use-presence@1.112.12(react@18.2.0)':
dependencies:
'@tamagui/web': 1.112.12(react@18.2.0)
@@ -18887,6 +19370,20 @@ snapshots:
'@tamagui/web': 1.112.12(react@18.2.0)
react: 18.2.0
+ '@tamagui/vite-plugin@1.101.3(encoding@0.1.13)(react@18.2.0)':
+ dependencies:
+ '@tamagui/fake-react-native': 1.101.3
+ '@tamagui/proxy-worm': 1.101.3
+ '@tamagui/react-native-svg': 1.101.3
+ '@tamagui/static': 1.101.3(encoding@0.1.13)(react@18.2.0)
+ esm-resolve: 1.0.11
+ fs-extra: 11.2.0
+ outdent: 0.8.0
+ transitivePeerDependencies:
+ - encoding
+ - react
+ - supports-color
+
'@tamagui/vite-plugin@1.112.12(@swc/helpers@0.5.13)(encoding@0.1.13)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)':
dependencies:
'@tamagui/fake-react-native': 1.112.12
@@ -18904,6 +19401,18 @@ snapshots:
- react-dom
- supports-color
+ '@tamagui/web@1.101.3':
+ dependencies:
+ '@tamagui/compose-refs': 1.101.3
+ '@tamagui/constants': 1.101.3
+ '@tamagui/helpers': 1.101.3
+ '@tamagui/normalize-css-color': 1.101.3
+ '@tamagui/timer': 1.101.3
+ '@tamagui/types': 1.101.3
+ '@tamagui/use-did-finish-ssr': 1.101.3
+ '@tamagui/use-event': 1.101.3
+ '@tamagui/use-force-update': 1.101.3
+
'@tamagui/web@1.112.12(react@18.2.0)':
dependencies:
'@tamagui/compose-refs': 1.112.12(react@18.2.0)
@@ -19801,33 +20310,33 @@ snapshots:
graphql: 15.8.0
wonka: 4.0.15
- '@vitejs/plugin-basic-ssl@1.1.0(vite@5.1.6(@types/node@20.10.8)(lightningcss@1.19.0)(terser@5.19.1))':
+ '@vitejs/plugin-basic-ssl@1.1.0(vite@5.1.6(@types/node@20.10.8)(terser@5.19.1))':
dependencies:
- vite: 5.1.6(@types/node@20.10.8)(lightningcss@1.19.0)(terser@5.19.1)
+ vite: 5.1.6(@types/node@20.10.8)(terser@5.19.1)
- '@vitejs/plugin-basic-ssl@1.1.0(vite@5.1.6(@types/node@20.14.10)(lightningcss@1.19.0)(terser@5.19.1))':
+ '@vitejs/plugin-basic-ssl@1.1.0(vite@5.1.6(@types/node@20.14.10)(terser@5.19.1))':
dependencies:
- vite: 5.1.6(@types/node@20.14.10)(lightningcss@1.19.0)(terser@5.19.1)
+ vite: 5.1.6(@types/node@20.14.10)(terser@5.19.1)
- '@vitejs/plugin-react@4.2.1(vite@5.1.6(@types/node@20.10.8)(lightningcss@1.19.0)(terser@5.19.1))':
+ '@vitejs/plugin-react@4.2.1(vite@5.1.6(@types/node@20.10.8)(terser@5.19.1))':
dependencies:
'@babel/core': 7.23.7
'@babel/plugin-transform-react-jsx-self': 7.23.3(@babel/core@7.23.7)
'@babel/plugin-transform-react-jsx-source': 7.23.3(@babel/core@7.23.7)
'@types/babel__core': 7.20.5
react-refresh: 0.14.0
- vite: 5.1.6(@types/node@20.10.8)(lightningcss@1.19.0)(terser@5.19.1)
+ vite: 5.1.6(@types/node@20.10.8)(terser@5.19.1)
transitivePeerDependencies:
- supports-color
- '@vitejs/plugin-react@4.2.1(vite@5.1.6(@types/node@20.14.10)(lightningcss@1.19.0)(terser@5.19.1))':
+ '@vitejs/plugin-react@4.2.1(vite@5.1.6(@types/node@20.14.10)(terser@5.19.1))':
dependencies:
- '@babel/core': 7.25.2
- '@babel/plugin-transform-react-jsx-self': 7.23.3(@babel/core@7.25.2)
- '@babel/plugin-transform-react-jsx-source': 7.23.3(@babel/core@7.25.2)
+ '@babel/core': 7.23.7
+ '@babel/plugin-transform-react-jsx-self': 7.23.3(@babel/core@7.23.7)
+ '@babel/plugin-transform-react-jsx-source': 7.23.3(@babel/core@7.23.7)
'@types/babel__core': 7.20.5
react-refresh: 0.14.0
- vite: 5.1.6(@types/node@20.14.10)(lightningcss@1.19.0)(terser@5.19.1)
+ vite: 5.1.6(@types/node@20.14.10)(terser@5.19.1)
transitivePeerDependencies:
- supports-color
@@ -21676,6 +22185,13 @@ snapshots:
es6-iterator: 2.0.3
es6-symbol: 3.1.4
+ esbuild-plugin-es5@2.1.1(esbuild@0.21.5):
+ dependencies:
+ '@swc/core': 1.7.26(@swc/helpers@0.5.13)
+ '@swc/helpers': 0.5.13
+ deepmerge: 4.3.1
+ esbuild: 0.21.5
+
esbuild-plugin-es5@2.1.1(esbuild@0.24.0):
dependencies:
'@swc/core': 1.7.26(@swc/helpers@0.5.13)
@@ -21690,6 +22206,13 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ esbuild-register@3.6.0(esbuild@0.21.5):
+ dependencies:
+ debug: 4.3.4
+ esbuild: 0.21.5
+ transitivePeerDependencies:
+ - supports-color
+
esbuild-register@3.6.0(esbuild@0.24.0):
dependencies:
debug: 4.3.4
@@ -21748,6 +22271,32 @@ snapshots:
'@esbuild/win32-ia32': 0.19.12
'@esbuild/win32-x64': 0.19.12
+ esbuild@0.21.5:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.21.5
+ '@esbuild/android-arm': 0.21.5
+ '@esbuild/android-arm64': 0.21.5
+ '@esbuild/android-x64': 0.21.5
+ '@esbuild/darwin-arm64': 0.21.5
+ '@esbuild/darwin-x64': 0.21.5
+ '@esbuild/freebsd-arm64': 0.21.5
+ '@esbuild/freebsd-x64': 0.21.5
+ '@esbuild/linux-arm': 0.21.5
+ '@esbuild/linux-arm64': 0.21.5
+ '@esbuild/linux-ia32': 0.21.5
+ '@esbuild/linux-loong64': 0.21.5
+ '@esbuild/linux-mips64el': 0.21.5
+ '@esbuild/linux-ppc64': 0.21.5
+ '@esbuild/linux-riscv64': 0.21.5
+ '@esbuild/linux-s390x': 0.21.5
+ '@esbuild/linux-x64': 0.21.5
+ '@esbuild/netbsd-x64': 0.21.5
+ '@esbuild/openbsd-x64': 0.21.5
+ '@esbuild/sunos-x64': 0.21.5
+ '@esbuild/win32-arm64': 0.21.5
+ '@esbuild/win32-ia32': 0.21.5
+ '@esbuild/win32-x64': 0.21.5
+
esbuild@0.24.0:
optionalDependencies:
'@esbuild/aix-ppc64': 0.24.0
@@ -23687,10 +24236,10 @@ snapshots:
jest-snapshot@29.7.0:
dependencies:
'@babel/core': 7.25.2
- '@babel/generator': 7.25.0
+ '@babel/generator': 7.25.6
'@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.25.2)
'@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.25.2)
- '@babel/types': 7.25.2
+ '@babel/types': 7.25.6
'@jest/expect-utils': 29.7.0
'@jest/transform': 29.7.0
'@jest/types': 29.6.3
@@ -25163,8 +25712,8 @@ snapshots:
dependencies:
fflate: 0.4.8
- ? posthog-react-native@2.11.3(@react-native-async-storage/async-storage@1.21.0(react-native@0.73.9(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2))(encoding@0.1.13)(react@18.2.0)))(@react-navigation/native@6.1.10(react-native@0.73.9(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2))(encoding@0.1.13)(react@18.2.0))(react@18.2.0))(expo-application@5.8.3(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13)))(expo-device@5.9.3(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13)))(expo-file-system@16.0.9(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13)))(expo-localization@14.8.3(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13)))(react-native-device-info@10.12.0(react-native@0.73.9(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2))(encoding@0.1.13)(react@18.2.0)))
- : optionalDependencies:
+ posthog-react-native@2.11.3(jwrxiw3lzqzjxcpw4mvkvmmdfa):
+ optionalDependencies:
'@react-native-async-storage/async-storage': 1.21.0(react-native@0.73.9(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2))(encoding@0.1.13)(react@18.2.0))
'@react-navigation/native': 6.1.10(react-native@0.73.9(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2))(encoding@0.1.13)(react@18.2.0))(react@18.2.0)
expo-application: 5.8.3(expo@50.0.6(@babel/core@7.25.2)(@react-native/babel-preset@0.73.21(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2)))(encoding@0.1.13))
@@ -25507,17 +26056,17 @@ snapshots:
react-cosmos-core: 6.1.1
react-cosmos-renderer: 6.1.1
- react-cosmos-plugin-vite@6.1.1(vite@5.1.6(@types/node@20.10.8)(lightningcss@1.19.0)(terser@5.19.1)):
+ react-cosmos-plugin-vite@6.1.1(vite@5.1.6(@types/node@20.10.8)(terser@5.19.1)):
dependencies:
react-cosmos-core: 6.1.1
react-cosmos-dom: 6.1.1
- vite: 5.1.6(@types/node@20.10.8)(lightningcss@1.19.0)(terser@5.19.1)
+ vite: 5.1.6(@types/node@20.10.8)(terser@5.19.1)
- react-cosmos-plugin-vite@6.1.1(vite@5.1.6(@types/node@20.14.10)(lightningcss@1.19.0)(terser@5.19.1)):
+ react-cosmos-plugin-vite@6.1.1(vite@5.1.6(@types/node@20.14.10)(terser@5.19.1)):
dependencies:
react-cosmos-core: 6.1.1
react-cosmos-dom: 6.1.1
- vite: 5.1.6(@types/node@20.14.10)(lightningcss@1.19.0)(terser@5.19.1)
+ vite: 5.1.6(@types/node@20.14.10)(terser@5.19.1)
react-cosmos-renderer@6.1.1:
dependencies:
@@ -25816,6 +26365,25 @@ snapshots:
react-native: 0.73.9(@babel/core@7.25.2)(@babel/preset-env@7.23.7(@babel/core@7.25.2))(encoding@0.1.13)(react@18.2.0)
whatwg-url-without-unicode: 8.0.0-3
+ react-native-web-internals@1.101.3:
+ dependencies:
+ '@tamagui/normalize-css-color': 1.101.3
+ '@tamagui/react-native-use-pressable': 1.101.3
+ '@tamagui/react-native-use-responder-events': 1.101.3
+ '@tamagui/simple-hash': 1.101.3
+ react: 18.2.0
+ styleq: 0.1.3
+
+ react-native-web-lite@1.101.3(react@18.2.0):
+ dependencies:
+ '@tamagui/normalize-css-color': 1.101.3
+ '@tamagui/react-native-use-pressable': 1.101.3
+ '@tamagui/react-native-use-responder-events': 1.101.3
+ invariant: 2.2.4
+ react: 18.2.0
+ react-native-web-internals: 1.101.3
+ styleq: 0.1.3
+
react-native-web@0.19.12(encoding@0.1.13)(react-dom@18.2.0(react@18.2.0))(react@18.2.0):
dependencies:
'@babel/runtime': 7.25.6
@@ -26309,6 +26877,15 @@ snapshots:
serialize-javascript: 4.0.0
terser: 5.19.1
+ rollup-plugin-visualizer@5.12.0(rollup@2.79.1):
+ dependencies:
+ open: 8.4.2
+ picomatch: 2.3.1
+ source-map: 0.7.4
+ yargs: 17.7.2
+ optionalDependencies:
+ rollup: 2.79.1
+
rollup-plugin-visualizer@5.12.0(rollup@4.13.0):
dependencies:
open: 8.4.2
@@ -27610,14 +28187,14 @@ snapshots:
react-dom: 18.2.0(react@18.2.0)
redux: 4.2.0
- vite-node@0.34.6(@types/node@20.10.8)(lightningcss@1.19.0)(terser@5.19.1):
+ vite-node@0.34.6(@types/node@20.10.8)(terser@5.19.1):
dependencies:
cac: 6.7.14
debug: 4.3.4
mlly: 1.5.0
pathe: 1.1.2
picocolors: 1.0.0
- vite: 5.1.6(@types/node@20.10.8)(lightningcss@1.19.0)(terser@5.19.1)
+ vite: 5.1.6(@types/node@20.10.8)(terser@5.19.1)
transitivePeerDependencies:
- '@types/node'
- less
@@ -27628,13 +28205,13 @@ snapshots:
- supports-color
- terser
- vite-node@1.2.2(@types/node@20.14.10)(lightningcss@1.19.0)(terser@5.19.1):
+ vite-node@1.2.2(@types/node@20.14.10)(terser@5.19.1):
dependencies:
cac: 6.7.14
debug: 4.3.4
pathe: 1.1.2
picocolors: 1.0.0
- vite: 5.1.6(@types/node@20.14.10)(lightningcss@1.19.0)(terser@5.19.1)
+ vite: 5.1.6(@types/node@20.14.10)(terser@5.19.1)
transitivePeerDependencies:
- '@types/node'
- less
@@ -27645,13 +28222,13 @@ snapshots:
- supports-color
- terser
- vite-node@1.5.0(@types/node@20.14.10)(lightningcss@1.19.0)(terser@5.19.1):
+ vite-node@1.5.0(@types/node@20.14.10)(terser@5.19.1):
dependencies:
cac: 6.7.14
debug: 4.3.4
pathe: 1.1.2
picocolors: 1.0.1
- vite: 5.1.6(@types/node@20.14.10)(lightningcss@1.19.0)(terser@5.19.1)
+ vite: 5.1.6(@types/node@20.14.10)(terser@5.19.1)
transitivePeerDependencies:
- '@types/node'
- less
@@ -27662,57 +28239,57 @@ snapshots:
- supports-color
- terser
- vite-plugin-pwa@0.17.5(vite@5.1.6(@types/node@20.10.8)(lightningcss@1.19.0)(terser@5.19.1))(workbox-build@7.0.0(@types/babel__core@7.20.5))(workbox-window@7.0.0):
+ vite-plugin-pwa@0.17.5(vite@5.1.6(@types/node@20.10.8)(terser@5.19.1))(workbox-build@7.0.0(@types/babel__core@7.20.5))(workbox-window@7.0.0):
dependencies:
debug: 4.3.4
fast-glob: 3.3.2
pretty-bytes: 6.1.1
- vite: 5.1.6(@types/node@20.10.8)(lightningcss@1.19.0)(terser@5.19.1)
+ vite: 5.1.6(@types/node@20.10.8)(terser@5.19.1)
workbox-build: 7.0.0(@types/babel__core@7.20.5)
workbox-window: 7.0.0
transitivePeerDependencies:
- supports-color
- vite-plugin-pwa@0.17.5(vite@5.1.6(@types/node@20.14.10)(lightningcss@1.19.0)(terser@5.19.1))(workbox-build@7.0.0(@types/babel__core@7.20.5))(workbox-window@7.0.0):
+ vite-plugin-pwa@0.17.5(vite@5.1.6(@types/node@20.14.10)(terser@5.19.1))(workbox-build@7.0.0(@types/babel__core@7.20.5))(workbox-window@7.0.0):
dependencies:
debug: 4.3.4
fast-glob: 3.3.2
pretty-bytes: 6.1.1
- vite: 5.1.6(@types/node@20.14.10)(lightningcss@1.19.0)(terser@5.19.1)
+ vite: 5.1.6(@types/node@20.14.10)(terser@5.19.1)
workbox-build: 7.0.0(@types/babel__core@7.20.5)
workbox-window: 7.0.0
transitivePeerDependencies:
- supports-color
- vite-plugin-singlefile@2.0.1(rollup@4.13.0)(vite@5.1.6(@types/node@20.14.10)(lightningcss@1.19.0)(terser@5.19.1)):
+ vite-plugin-singlefile@2.0.1(rollup@4.13.0)(vite@5.1.6(@types/node@20.14.10)(terser@5.19.1)):
dependencies:
micromatch: 4.0.5
rollup: 4.13.0
- vite: 5.1.6(@types/node@20.14.10)(lightningcss@1.19.0)(terser@5.19.1)
+ vite: 5.1.6(@types/node@20.14.10)(terser@5.19.1)
- vite-plugin-svgr@4.2.0(rollup@4.13.0)(typescript@5.4.5)(vite@5.1.6(@types/node@20.10.8)(lightningcss@1.19.0)(terser@5.19.1)):
+ vite-plugin-svgr@4.2.0(rollup@2.79.1)(typescript@5.4.5)(vite@5.1.6(@types/node@20.10.8)(terser@5.19.1)):
dependencies:
- '@rollup/pluginutils': 5.1.0(rollup@4.13.0)
+ '@rollup/pluginutils': 5.1.0(rollup@2.79.1)
'@svgr/core': 8.1.0(typescript@5.4.5)
'@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.4.5))
- vite: 5.1.6(@types/node@20.10.8)(lightningcss@1.19.0)(terser@5.19.1)
+ vite: 5.1.6(@types/node@20.10.8)(terser@5.19.1)
transitivePeerDependencies:
- rollup
- supports-color
- typescript
- vite-plugin-svgr@4.2.0(rollup@4.13.0)(typescript@5.4.5)(vite@5.1.6(@types/node@20.14.10)(lightningcss@1.19.0)(terser@5.19.1)):
+ vite-plugin-svgr@4.2.0(rollup@4.13.0)(typescript@5.4.5)(vite@5.1.6(@types/node@20.14.10)(terser@5.19.1)):
dependencies:
'@rollup/pluginutils': 5.1.0(rollup@4.13.0)
'@svgr/core': 8.1.0(typescript@5.4.5)
'@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.4.5))
- vite: 5.1.6(@types/node@20.14.10)(lightningcss@1.19.0)(terser@5.19.1)
+ vite: 5.1.6(@types/node@20.14.10)(terser@5.19.1)
transitivePeerDependencies:
- rollup
- supports-color
- typescript
- vite@5.1.6(@types/node@20.10.8)(lightningcss@1.19.0)(terser@5.19.1):
+ vite@5.1.6(@types/node@20.10.8)(terser@5.19.1):
dependencies:
esbuild: 0.19.12
postcss: 8.4.35
@@ -27720,10 +28297,9 @@ snapshots:
optionalDependencies:
'@types/node': 20.10.8
fsevents: 2.3.3
- lightningcss: 1.19.0
terser: 5.19.1
- vite@5.1.6(@types/node@20.14.10)(lightningcss@1.19.0)(terser@5.19.1):
+ vite@5.1.6(@types/node@20.14.10)(terser@5.19.1):
dependencies:
esbuild: 0.19.12
postcss: 8.4.35
@@ -27731,10 +28307,9 @@ snapshots:
optionalDependencies:
'@types/node': 20.14.10
fsevents: 2.3.3
- lightningcss: 1.19.0
terser: 5.19.1
- vitest@0.34.6(jsdom@23.2.0)(lightningcss@1.19.0)(terser@5.19.1):
+ vitest@0.34.6(jsdom@23.2.0)(terser@5.19.1):
dependencies:
'@types/chai': 4.3.11
'@types/chai-subset': 1.3.5
@@ -27757,8 +28332,8 @@ snapshots:
strip-literal: 1.3.0
tinybench: 2.6.0
tinypool: 0.7.0
- vite: 5.1.6(@types/node@20.10.8)(lightningcss@1.19.0)(terser@5.19.1)
- vite-node: 0.34.6(@types/node@20.10.8)(lightningcss@1.19.0)(terser@5.19.1)
+ vite: 5.1.6(@types/node@20.10.8)(terser@5.19.1)
+ vite-node: 0.34.6(@types/node@20.10.8)(terser@5.19.1)
why-is-node-running: 2.2.2
optionalDependencies:
jsdom: 23.2.0
@@ -27771,7 +28346,7 @@ snapshots:
- supports-color
- terser
- vitest@1.2.2(@types/node@20.14.10)(jsdom@23.2.0)(lightningcss@1.19.0)(terser@5.19.1):
+ vitest@1.2.2(@types/node@20.14.10)(jsdom@23.2.0)(terser@5.19.1):
dependencies:
'@vitest/expect': 1.2.2
'@vitest/runner': 1.2.2
@@ -27791,8 +28366,8 @@ snapshots:
strip-literal: 1.3.0
tinybench: 2.6.0
tinypool: 0.8.2
- vite: 5.1.6(@types/node@20.14.10)(lightningcss@1.19.0)(terser@5.19.1)
- vite-node: 1.2.2(@types/node@20.14.10)(lightningcss@1.19.0)(terser@5.19.1)
+ vite: 5.1.6(@types/node@20.14.10)(terser@5.19.1)
+ vite-node: 1.2.2(@types/node@20.14.10)(terser@5.19.1)
why-is-node-running: 2.2.2
optionalDependencies:
'@types/node': 20.14.10
@@ -27806,7 +28381,7 @@ snapshots:
- supports-color
- terser
- vitest@1.5.0(@types/node@20.14.10)(jsdom@23.2.0)(lightningcss@1.19.0)(terser@5.19.1):
+ vitest@1.5.0(@types/node@20.14.10)(jsdom@23.2.0)(terser@5.19.1):
dependencies:
'@vitest/expect': 1.5.0
'@vitest/runner': 1.5.0
@@ -27825,8 +28400,8 @@ snapshots:
strip-literal: 2.1.0
tinybench: 2.6.0
tinypool: 0.8.4
- vite: 5.1.6(@types/node@20.14.10)(lightningcss@1.19.0)(terser@5.19.1)
- vite-node: 1.5.0(@types/node@20.14.10)(lightningcss@1.19.0)(terser@5.19.1)
+ vite: 5.1.6(@types/node@20.14.10)(terser@5.19.1)
+ vite-node: 1.5.0(@types/node@20.14.10)(terser@5.19.1)
why-is-node-running: 2.2.2
optionalDependencies:
'@types/node': 20.14.10