diff --git a/.github/workflows/mobile-build.yml b/.github/workflows/mobile-build.yml index 026a436b79..8490333a7b 100644 --- a/.github/workflows/mobile-build.yml +++ b/.github/workflows/mobile-build.yml @@ -15,9 +15,6 @@ on: - all - android - ios -env: - NOTIFY_PROVIDER: rivfur-livmet - NOTIFY_SERVICE: groups-native jobs: deploy: runs-on: ubuntu-latest @@ -36,9 +33,15 @@ jobs: token: ${{ secrets.EXPO_TOKEN }} - name: Install dependencies run: npm ci + - name: Create build vars + id: vars + run: | + echo "profile=${{ inputs.profile || 'preview' }}" >> $GITHUB_OUTPUT - name: Build for selected platforms working-directory: ./apps/tlon-mobile - run: eas build --profile ${{ inputs.profile || 'preview' }} --platform ${{ inputs.platform || 'all' }} --non-interactive --auto-submit + run: eas build --profile ${{ steps.vars.outputs.profile }} --platform ${{ inputs.platform || 'all' }} --non-interactive --auto-submit env: EXPO_APPLE_ID: ${{ secrets.EXPO_APPLE_ID }} EXPO_APPLE_PASSWORD: ${{ secrets.EXPO_APPLE_PASSWORD }} + NOTIFY_PROVIDER: "${{ steps.vars.outputs.profile == 'preview' && 'binnec-dozzod-marnus' || 'rivfur-livmet' }}" + NOTIFY_SERVICE: "${{ steps.vars.outputs.profile == 'preview' && 'tlon-preview-release' || 'groups-native' }}" diff --git a/.github/workflows/mobile-update.yml b/.github/workflows/mobile-update.yml index 0087665408..f68441c4d9 100644 --- a/.github/workflows/mobile-update.yml +++ b/.github/workflows/mobile-update.yml @@ -15,9 +15,6 @@ on: - all - android - ios -env: - NOTIFY_PROVIDER: rivfur-livmet - NOTIFY_SERVICE: groups-native jobs: deploy: runs-on: ubuntu-latest @@ -36,6 +33,13 @@ jobs: token: ${{ secrets.EXPO_TOKEN }} - name: Install dependencies run: npm ci + - name: Create build vars + id: vars + run: | + echo "profile=${{ inputs.profile || 'preview' }}" >> $GITHUB_OUTPUT - name: Push update for selected platforms working-directory: ./apps/tlon-mobile - run: eas update --auto --profile ${{ inputs.profile || 'preview' }} --platform ${{ inputs.platform || 'all' }} --non-interactive + run: eas update --auto --profile ${{ steps.vars.outputs.profile }} --platform ${{ inputs.platform || 'all' }} --non-interactive + env: + NOTIFY_PROVIDER: "${{ steps.vars.outputs.profile == 'preview' && 'binnec-dozzod-marnus' || 'rivfur-livmet' }}" + NOTIFY_SERVICE: "${{ steps.vars.outputs.profile == 'preview' && 'tlon-preview-release' || 'groups-native' }}" diff --git a/apps/tlon-mobile/.env.sample b/apps/tlon-mobile/.env.sample index e21f49f9a1..bf26e98a05 100644 --- a/apps/tlon-mobile/.env.sample +++ b/apps/tlon-mobile/.env.sample @@ -9,3 +9,7 @@ DEFAULT_LURE= DEFAULT_PRIORITY_TOKEN= RECAPTCHA_SITE_KEY_ANDROID= RECAPTCHA_SITE_KEY_IOS= +DEFAULT_TLON_LOGIN_EMAIL= +DEFAULT_TLON_LOGIN_PASSWORD= +DEFAULT_SHIP_LOGIN_URL= +DEFAULT_SHIP_LOGIN_ACCESS_CODE= diff --git a/apps/tlon-mobile/README.md b/apps/tlon-mobile/README.md index ca12dd70ba..8eb9affebd 100644 --- a/apps/tlon-mobile/README.md +++ b/apps/tlon-mobile/README.md @@ -70,6 +70,37 @@ Plug in your iOS device or start the iPhone Simulator and run the application in npm run ios ``` +#### Run Preview Scheme + +Run the Preview version of the app by specifying `scheme` or `variant` in the run command: + +```sh +npm run ios -- --scheme=Landscape-preview +``` + +```sh +npm run android -- --variant=preview +``` + +## Debugging + +### Dev tools + +Press `j` while running expo-cli/metro to open chrome devtools. You can use the devtools to view logs, network requests, and more. [More info here](https://docs.expo.dev/debugging/tools/#debugging-with-chrome-devtools). + +### Default Credentials + +To streamline testing the login flow, you can use env variables to prepopulate fields in the Tlon Login and ship login screen. The relevant variables are: + +``` +DEFAULT_TLON_LOGIN_EMAIL= +DEFAULT_TLON_LOGIN_PASSWORD= +DEFAULT_SHIP_LOGIN_URL= +DEFAULT_SHIP_LOGIN_ACCESS_CODE= +``` + +See `.env.sample` for other configurable env variables. + ## Deployment Deployment is handled by [Expo Application Services](https://expo.dev/eas). diff --git a/apps/tlon-mobile/android/app/google-services.json b/apps/tlon-mobile/android/app/google-services.json index 7f3b21a7f8..f99c9075f4 100644 --- a/apps/tlon-mobile/android/app/google-services.json +++ b/apps/tlon-mobile/android/app/google-services.json @@ -12,12 +12,7 @@ "package_name": "io.tlon.groups" } }, - "oauth_client": [ - { - "client_id": "543296749236-1l5r4ipguvjdh083t5j7h1eicqi21j0o.apps.googleusercontent.com", - "client_type": 3 - } - ], + "oauth_client": [], "api_key": [ { "current_key": "AIzaSyDm8-5daeW5B8j6i_RIoSvOgnx6Fo0gEOU" @@ -25,12 +20,7 @@ ], "services": { "appinvite_service": { - "other_platform_oauth_client": [ - { - "client_id": "543296749236-1l5r4ipguvjdh083t5j7h1eicqi21j0o.apps.googleusercontent.com", - "client_type": 3 - } - ] + "other_platform_oauth_client": [] } } }, @@ -41,12 +31,7 @@ "package_name": "io.tlon.groups.preview" } }, - "oauth_client": [ - { - "client_id": "543296749236-1l5r4ipguvjdh083t5j7h1eicqi21j0o.apps.googleusercontent.com", - "client_type": 3 - } - ], + "oauth_client": [], "api_key": [ { "current_key": "AIzaSyDm8-5daeW5B8j6i_RIoSvOgnx6Fo0gEOU" @@ -54,12 +39,7 @@ ], "services": { "appinvite_service": { - "other_platform_oauth_client": [ - { - "client_id": "543296749236-1l5r4ipguvjdh083t5j7h1eicqi21j0o.apps.googleusercontent.com", - "client_type": 3 - } - ] + "other_platform_oauth_client": [] } } } diff --git a/apps/tlon-mobile/app.config.ts b/apps/tlon-mobile/app.config.ts index 7b59b14039..868d7e9115 100644 --- a/apps/tlon-mobile/app.config.ts +++ b/apps/tlon-mobile/app.config.ts @@ -23,10 +23,12 @@ export default ({ config }: ConfigContext): ExpoConfig => ({ shipUrlPattern: process.env.SHIP_URL_PATTERN, defaultLure: process.env.DEFAULT_LURE, defaultPriorityToken: process.env.DEFAULT_PRIORITY_TOKEN, + defaultTlonLoginEmail: process.env.DEFAULT_TLON_LOGIN_EMAIL, + defaultTlonLoginPassword: process.env.DEFAULT_TLON_LOGIN_PASSWORD, + defaultShipLoginUrl: process.env.DEFAULT_SHIP_LOGIN_URL, + defaultShipLoginAccessCode: process.env.DEFAULT_SHIP_LOGIN_ACCESS_CODE, recaptchaSiteKeyAndroid: process.env.RECAPTCHA_SITE_KEY_ANDROID, recaptchaSiteKeyIOS: process.env.RECAPTCHA_SITE_KEY_IOS, - devLocal: Boolean(process.env.DEV_LOCAL), - devLocalCode: process.env.DEV_LOCAL_CODE, }, ios: { runtimeVersion: '4.0.0', diff --git a/apps/tlon-mobile/index.js b/apps/tlon-mobile/index.js index d0b1debe2a..4fd359d5a0 100644 --- a/apps/tlon-mobile/index.js +++ b/apps/tlon-mobile/index.js @@ -1,4 +1,5 @@ import { registerRootComponent } from 'expo'; +import 'expo-dev-client'; import { TailwindProvider } from 'tailwind-rn'; import App from './src/App'; diff --git a/apps/tlon-mobile/ios/Landscape.xcodeproj/project.pbxproj b/apps/tlon-mobile/ios/Landscape.xcodeproj/project.pbxproj index cc55580059..2c100a82d2 100644 --- a/apps/tlon-mobile/ios/Landscape.xcodeproj/project.pbxproj +++ b/apps/tlon-mobile/ios/Landscape.xcodeproj/project.pbxproj @@ -482,7 +482,7 @@ mainGroup = 83CBB9F61A601CBA00E9B192; packageReferences = ( 70A62C5F2A5A6B1A00EBED16 /* XCRemoteSwiftPackageReference "SimpleKeychain" */, - 70D386462A6098F800AFB46E /* XCRemoteSwiftPackageReference "Alamofire" */, + 70D386462A6098F800AFB46E /* XCRemoteSwiftPackageReference "Alamofire.git" */, 70D3866D2A60A3B300AFB46E /* XCRemoteSwiftPackageReference "UrsusSigil" */, ); productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */; @@ -653,12 +653,16 @@ "${PODS_CONFIGURATION_BUILD_DIR}/EXConstants/EXConstants.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/EXUpdates/EXUpdates.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/React-Core/RCTI18nStrings.bundle", + "${PODS_CONFIGURATION_BUILD_DIR}/expo-dev-launcher/EXDevLauncher.bundle", + "${PODS_CONFIGURATION_BUILD_DIR}/expo-dev-menu/EXDevMenu.bundle", ); name = "[CP] Copy Pods Resources"; outputPaths = ( "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EXConstants.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EXUpdates.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCTI18nStrings.bundle", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EXDevLauncher.bundle", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EXDevMenu.bundle", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -729,12 +733,16 @@ "${PODS_CONFIGURATION_BUILD_DIR}/EXConstants/EXConstants.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/EXUpdates/EXUpdates.bundle", "${PODS_CONFIGURATION_BUILD_DIR}/React-Core/RCTI18nStrings.bundle", + "${PODS_CONFIGURATION_BUILD_DIR}/expo-dev-launcher/EXDevLauncher.bundle", + "${PODS_CONFIGURATION_BUILD_DIR}/expo-dev-menu/EXDevMenu.bundle", ); name = "[CP] Copy Pods Resources"; outputPaths = ( "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EXConstants.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EXUpdates.bundle", "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCTI18nStrings.bundle", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EXDevLauncher.bundle", + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EXDevMenu.bundle", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -1360,7 +1368,7 @@ minimumVersion = 1.0.0; }; }; - 70D386462A6098F800AFB46E /* XCRemoteSwiftPackageReference "Alamofire" */ = { + 70D386462A6098F800AFB46E /* XCRemoteSwiftPackageReference "Alamofire.git" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/Alamofire/Alamofire.git"; requirement = { @@ -1384,7 +1392,7 @@ minimumVersion = 1.0.0; }; }; - 70DBBFE32B7C60B50021EA96 /* XCRemoteSwiftPackageReference "Alamofire" */ = { + 70DBBFE32B7C60B50021EA96 /* XCRemoteSwiftPackageReference "Alamofire.git" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/Alamofire/Alamofire.git"; requirement = { @@ -1410,7 +1418,7 @@ }; 70D386472A6098F800AFB46E /* Alamofire */ = { isa = XCSwiftPackageProductDependency; - package = 70D386462A6098F800AFB46E /* XCRemoteSwiftPackageReference "Alamofire" */; + package = 70D386462A6098F800AFB46E /* XCRemoteSwiftPackageReference "Alamofire.git" */; productName = Alamofire; }; 70D3866E2A60A3B300AFB46E /* UrsusSigil */ = { @@ -1425,7 +1433,7 @@ }; 70DBBFE22B7C60B50021EA96 /* Alamofire */ = { isa = XCSwiftPackageProductDependency; - package = 70DBBFE32B7C60B50021EA96 /* XCRemoteSwiftPackageReference "Alamofire" */; + package = 70DBBFE32B7C60B50021EA96 /* XCRemoteSwiftPackageReference "Alamofire.git" */; productName = Alamofire; }; 70DBBFE42B7C60B50021EA96 /* UrsusSigil */ = { diff --git a/apps/tlon-mobile/ios/Podfile.lock b/apps/tlon-mobile/ios/Podfile.lock index 7aaa2afc03..345c0c5abb 100644 --- a/apps/tlon-mobile/ios/Podfile.lock +++ b/apps/tlon-mobile/ios/Podfile.lock @@ -17,6 +17,73 @@ PODS: - ExpoModulesCore - Expo (50.0.6): - ExpoModulesCore + - expo-dev-client (3.3.9): + - EXManifests + - expo-dev-launcher + - expo-dev-menu + - expo-dev-menu-interface + - EXUpdatesInterface + - expo-dev-launcher (3.6.7): + - EXManifests + - expo-dev-launcher/Main (= 3.6.7) + - expo-dev-menu + - expo-dev-menu-interface + - ExpoModulesCore + - EXUpdatesInterface + - glog + - RCT-Folly (= 2022.05.16.00) + - React-Core + - React-RCTAppDelegate + - expo-dev-launcher/Main (3.6.7): + - EXManifests + - expo-dev-launcher/Unsafe + - expo-dev-menu + - expo-dev-menu-interface + - ExpoModulesCore + - EXUpdatesInterface + - glog + - RCT-Folly (= 2022.05.16.00) + - React-Core + - React-RCTAppDelegate + - expo-dev-launcher/Unsafe (3.6.7): + - EXManifests + - expo-dev-menu + - expo-dev-menu-interface + - ExpoModulesCore + - EXUpdatesInterface + - glog + - RCT-Folly (= 2022.05.16.00) + - React-Core + - React-RCTAppDelegate + - expo-dev-menu (4.5.6): + - expo-dev-menu/Main (= 4.5.6) + - expo-dev-menu/ReactNativeCompatibles (= 4.5.6) + - glog + - RCT-Folly (= 2022.05.16.00) + - React-Core + - expo-dev-menu-interface (1.7.2) + - expo-dev-menu/Main (4.5.6): + - EXManifests + - expo-dev-menu-interface + - expo-dev-menu/Vendored + - ExpoModulesCore + - glog + - RCT-Folly (= 2022.05.16.00) + - React-Core + - expo-dev-menu/ReactNativeCompatibles (4.5.6): + - glog + - RCT-Folly (= 2022.05.16.00) + - React-Core + - expo-dev-menu/SafeAreaView (4.5.6): + - ExpoModulesCore + - glog + - RCT-Folly (= 2022.05.16.00) + - React-Core + - expo-dev-menu/Vendored (4.5.6): + - expo-dev-menu/SafeAreaView + - glog + - RCT-Folly (= 2022.05.16.00) + - React-Core - ExpoClipboard (5.0.1): - ExpoModulesCore - ExpoDevice (5.9.3): @@ -1227,6 +1294,10 @@ DEPENDENCIES: - EXManifests (from `../../../node_modules/expo-manifests/ios`) - EXNotifications (from `../../../node_modules/expo-notifications/ios`) - Expo (from `../../../node_modules/expo`) + - expo-dev-client (from `../../../node_modules/expo-dev-client/ios`) + - expo-dev-launcher (from `../../../node_modules/expo-dev-launcher`) + - expo-dev-menu (from `../../../node_modules/expo-dev-menu`) + - expo-dev-menu-interface (from `../../../node_modules/expo-dev-menu-interface/ios`) - ExpoClipboard (from `../../../node_modules/expo-clipboard/ios`) - ExpoDevice (from `../../../node_modules/expo-device/ios`) - ExpoFileSystem (from `../../../node_modules/expo-file-system/ios`) @@ -1348,6 +1419,14 @@ EXTERNAL SOURCES: :path: "../../../node_modules/expo-notifications/ios" Expo: :path: "../../../node_modules/expo" + expo-dev-client: + :path: "../../../node_modules/expo-dev-client/ios" + expo-dev-launcher: + :path: "../../../node_modules/expo-dev-launcher" + expo-dev-menu: + :path: "../../../node_modules/expo-dev-menu" + expo-dev-menu-interface: + :path: "../../../node_modules/expo-dev-menu-interface/ios" ExpoClipboard: :path: "../../../node_modules/expo-clipboard/ios" ExpoDevice: @@ -1508,6 +1587,10 @@ SPEC CHECKSUMS: EXManifests: 5e8c29f36c716af768a4ea47ec05e1b89ab93091 EXNotifications: e11f0e9a5b657c064a481a5d522f3bc5a07bf7cd Expo: fb745b3074989670b6641f9f20463e8ee56a69ca + expo-dev-client: dbc8e8a81d17a9d92e083a2856d056ba9a58984d + expo-dev-launcher: fcdb0f3e91c34778f0816b0f590c7a57f052a87c + expo-dev-menu: 166fc9c7b82641cdead1dc26d958d20a127ee97b + expo-dev-menu-interface: 7ba029c9d1a82ac22b9b584c00514860b060553e ExpoClipboard: b597982124f067ff9f5b89093eb3d97898d5d877 ExpoDevice: d204395e17fffdcefa7470bdef33b07719ac41b1 ExpoFileSystem: a9273932e69a9a1e1a8d01b6ba895bb8294bbea2 @@ -1599,7 +1682,7 @@ SPEC CHECKSUMS: SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17 sqlite3: f163dbbb7aa3339ad8fc622782c2d9d7b72f7e9c UMAppLoader: 5df85360d65cabaef544be5424ac64672e648482 - Yoga: 1b901a6d6eeba4e8a2e8f308f708691cdb5db312 + Yoga: 64cd2a583ead952b0315d5135bf39e053ae9be70 PODFILE CHECKSUM: 82da24eb176d4abdeaf445b3581717ec492dd7e8 diff --git a/apps/tlon-mobile/package.json b/apps/tlon-mobile/package.json index 3112f1ae71..feb21cd41a 100644 --- a/apps/tlon-mobile/package.json +++ b/apps/tlon-mobile/package.json @@ -48,6 +48,7 @@ "expo-asset": "~9.0.2", "expo-clipboard": "~5.0.1", "expo-constants": "~15.4.5", + "expo-dev-client": "^3.3.9", "expo-device": "~5.9.3", "expo-file-system": "~16.0.6", "expo-localization": "~14.8.3", diff --git a/apps/tlon-mobile/src/App.tsx b/apps/tlon-mobile/src/App.tsx index 125dcdc6d6..97784fc3e4 100644 --- a/apps/tlon-mobile/src/App.tsx +++ b/apps/tlon-mobile/src/App.tsx @@ -15,14 +15,12 @@ import { useTailwind } from 'tailwind-rn'; import AuthenticatedApp from './components/AuthenticatedApp'; import { LoadingSpinner } from './components/LoadingSpinner'; -import { DEV_LOCAL, DEV_LOCAL_CODE } from './constants'; import { BranchProvider, useBranch } from './contexts/branch'; import { ShipProvider, useShip } from './contexts/ship'; import * as db from './db'; import { useIsDarkMode } from './hooks/useIsDarkMode'; import { useScreenOptions } from './hooks/useScreenOptions'; import { syncContacts } from './lib/sync'; -import { useDevTools } from './lib/useDevTools'; import { CheckVerifyScreen } from './screens/CheckVerifyScreen'; import { EULAScreen } from './screens/EULAScreen'; import { JoinWaitListScreen } from './screens/JoinWaitListScreen'; @@ -50,7 +48,6 @@ const OnboardingStack = createNativeStackNavigator(); // on Android if a notification click causes the app to open, the corresponding notification // path is passed in here as "wer" const App = ({ wer }: Props) => { - useDevTools({ enabled: DEV_LOCAL, localCode: DEV_LOCAL_CODE }); const isDarkMode = useIsDarkMode(); const tailwind = useTailwind(); const { isLoading, isAuthenticated } = useShip(); diff --git a/apps/tlon-mobile/src/components/SingletonWebview.tsx b/apps/tlon-mobile/src/components/SingletonWebview.tsx index 104b98044c..fd068ee146 100644 --- a/apps/tlon-mobile/src/components/SingletonWebview.tsx +++ b/apps/tlon-mobile/src/components/SingletonWebview.tsx @@ -16,7 +16,7 @@ import type { } from 'react-native-webview/lib/WebViewTypes'; import { useTailwind } from 'tailwind-rn'; -import { DEV_LOCAL } from '../constants'; +import { DEFAULT_SHIP_LOGIN_URL, DEFAULT_TLON_LOGIN_EMAIL } from '../constants'; import { useShip } from '../contexts/ship'; import { useWebViewContext } from '../contexts/webview/webview'; import useAppStatus from '../hooks/useAppStatus'; @@ -204,7 +204,8 @@ export const SingletonWebview = () => { window.colorscheme="${nativeOptions.colorScheme}"; window.safeAreaInsets=${JSON.stringify(nativeOptions.safeAreaInsets)}; ${ - DEV_LOCAL + // in development, explicitly set Urbit runtime configured window vars + DEFAULT_SHIP_LOGIN_URL || DEFAULT_TLON_LOGIN_EMAIL ? ` window.our="${ship}"; window.ship="${ship?.slice(1)}"; ` : '' } diff --git a/apps/tlon-mobile/src/constants.ts b/apps/tlon-mobile/src/constants.ts index f2b6000e6d..a5a9801f0f 100644 --- a/apps/tlon-mobile/src/constants.ts +++ b/apps/tlon-mobile/src/constants.ts @@ -27,6 +27,8 @@ export const SHIP_URL_PATTERN = extra.shipUrlPattern ?? 'https://{shipId}.tlon.network'; export const DEFAULT_LURE = extra.defaultLure ?? '~nibset-napwyn/tlon'; export const DEFAULT_PRIORITY_TOKEN = extra.defaultPriorityToken ?? 'mobile'; - -export const DEV_LOCAL = extra.devLocal ? Boolean(extra.devLocal) : false; -export const DEV_LOCAL_CODE = extra.devLocalCode ?? ''; +export const DEFAULT_TLON_LOGIN_EMAIL = extra.defaultTlonLoginEmail ?? ''; +export const DEFAULT_TLON_LOGIN_PASSWORD = extra.defaultTlonLoginPassword ?? ''; +export const DEFAULT_SHIP_LOGIN_URL = extra.defaultShipLoginUrl ?? ''; +export const DEFAULT_SHIP_LOGIN_ACCESS_CODE = + extra.defaultShipLoginAccessCode ?? ''; diff --git a/apps/tlon-mobile/src/lib/useDevTools.ts b/apps/tlon-mobile/src/lib/useDevTools.ts deleted file mode 100644 index d6130e353a..0000000000 --- a/apps/tlon-mobile/src/lib/useDevTools.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { useEffect } from 'react'; - -import { useShip } from '../contexts/ship'; -import { getShipFromCookie } from '../utils/ship'; -import { getLandscapeAuthCookie } from './landscapeApi'; - -const DEV_SHIP_URL = 'http://localhost:3000'; - -export function useDevTools(config: { enabled: boolean; localCode: string }) { - const { setShip, clearShip } = useShip(); - - // For use with local development. If the env vars DEV_LOCAL and DEV_LOCAL_CODE are set, - // will attempt to automatically authenticate you to the tlon-web dev server - useEffect(() => { - async function setupDevAuth() { - let cookie = null; - try { - cookie = await getLandscapeAuthCookie(DEV_SHIP_URL, config.localCode); - } catch (e) { - console.error('Error getting development auth cookie:', e); - } - - if (cookie) { - const ship = getShipFromCookie(cookie); - setShip({ - ship, - shipUrl: DEV_SHIP_URL, - }); - console.log(`Development auth configured for ${ship}`); - } else { - console.warn('Failed to set up development auth'); - clearShip(); - } - } - - if (config.enabled) { - if (!config.localCode) { - console.warn('No code found, skipping development auth'); - return; - } - setupDevAuth(); - } - }, []); -} diff --git a/apps/tlon-mobile/src/screens/ShipLoginScreen.tsx b/apps/tlon-mobile/src/screens/ShipLoginScreen.tsx index f6fefc7d4e..4c0d5a2786 100644 --- a/apps/tlon-mobile/src/screens/ShipLoginScreen.tsx +++ b/apps/tlon-mobile/src/screens/ShipLoginScreen.tsx @@ -6,7 +6,11 @@ import { useTailwind } from 'tailwind-rn'; import { HeaderButton } from '../components/HeaderButton'; import { LoadingSpinner } from '../components/LoadingSpinner'; -import { ACCESS_CODE_REGEX } from '../constants'; +import { + ACCESS_CODE_REGEX, + DEFAULT_SHIP_LOGIN_ACCESS_CODE, + DEFAULT_SHIP_LOGIN_URL, +} from '../constants'; import { useShip } from '../contexts/ship'; import { getLandscapeAuthCookie } from '../lib/landscapeApi'; import type { OnboardingStackParamList } from '../types'; @@ -34,7 +38,12 @@ export const ShipLoginScreen = ({ navigation }: Props) => { handleSubmit, formState: { errors }, setValue, - } = useForm(); + } = useForm({ + defaultValues: { + shipUrl: DEFAULT_SHIP_LOGIN_URL, + accessCode: DEFAULT_SHIP_LOGIN_ACCESS_CODE, + }, + }); const { setShip } = useShip(); const onSubmit = handleSubmit(async ({ shipUrl: rawShipUrl, accessCode }) => { diff --git a/apps/tlon-mobile/src/screens/TlonLoginScreen.tsx b/apps/tlon-mobile/src/screens/TlonLoginScreen.tsx index 22d6d467aa..f31d476088 100644 --- a/apps/tlon-mobile/src/screens/TlonLoginScreen.tsx +++ b/apps/tlon-mobile/src/screens/TlonLoginScreen.tsx @@ -6,6 +6,10 @@ import { useTailwind } from 'tailwind-rn'; import { HeaderButton } from '../components/HeaderButton'; import { LoadingSpinner } from '../components/LoadingSpinner'; +import { + DEFAULT_TLON_LOGIN_EMAIL, + DEFAULT_TLON_LOGIN_PASSWORD, +} from '../constants'; import { useShip } from '../contexts/ship'; import { getShipAccessCode, @@ -35,7 +39,12 @@ export const TlonLoginScreen = ({ navigation }: Props) => { handleSubmit, formState: { errors }, getValues, - } = useForm(); + } = useForm({ + defaultValues: { + email: DEFAULT_TLON_LOGIN_EMAIL, + password: DEFAULT_TLON_LOGIN_PASSWORD, + }, + }); const { setShip } = useShip(); const handleForgotPassword = () => { diff --git a/apps/tlon-web/src/chat/ChatInput/ChatInput.tsx b/apps/tlon-web/src/chat/ChatInput/ChatInput.tsx index a0857630f3..0da270af8e 100644 --- a/apps/tlon-web/src/chat/ChatInput/ChatInput.tsx +++ b/apps/tlon-web/src/chat/ChatInput/ChatInput.tsx @@ -394,6 +394,7 @@ export default function ChatInput({ lastMessageIdRef.current && !isEditing && !editor.isDestroyed && + editor.isEmpty && // don't allow editing of DM/Group DM messages until we support it // on the backend. !isDmOrMultiDM diff --git a/apps/tlon-web/src/chat/ChatScroller/ChatScroller.tsx b/apps/tlon-web/src/chat/ChatScroller/ChatScroller.tsx index 3fb4997509..4f94c4c1ad 100644 --- a/apps/tlon-web/src/chat/ChatScroller/ChatScroller.tsx +++ b/apps/tlon-web/src/chat/ChatScroller/ChatScroller.tsx @@ -27,6 +27,7 @@ import { useInvertedScrollInteraction, useUserHasScrolled, } from '@/logic/scroll'; +import useIsEditingMessage from '@/logic/useIsEditingMessage'; import { useIsMobile } from '@/logic/useMedia'; import { ChatMessageListItemData, @@ -214,6 +215,7 @@ export default function ChatScroller({ const contentElementRef = useRef(null); const { userHasScrolled, resetUserHasScrolled } = useUserHasScrolled(scrollElementRef); + const isEditing = useIsEditingMessage(); // Update the tracked load direction when loading state changes. useEffect(() => { @@ -482,7 +484,7 @@ export default function ChatScroller({ virtualizerRef.current = virtualizer; useFakeVirtuosoHandle(scrollerRef, virtualizer); - useInvertedScrollInteraction(scrollElementRef, isInverted); + useInvertedScrollInteraction(scrollElementRef, isInverted, isEditing); // Load more items when list reaches the top or bottom. useEffect(() => { diff --git a/apps/tlon-web/src/logic/scroll.ts b/apps/tlon-web/src/logic/scroll.ts index 287a3b224d..fe10d998e3 100644 --- a/apps/tlon-web/src/logic/scroll.ts +++ b/apps/tlon-web/src/logic/scroll.ts @@ -55,13 +55,15 @@ export function useIsScrolling( */ export function useInvertedScrollInteraction( scrollElementRef: RefObject, - isInverted: boolean + isInverted: boolean, + // isEditing must be passed in rather than using useIsEditingMessage because + // it won't update if we use it here. + isEditing: boolean ) { - const isEditing = useIsEditingMessage(); - useEffect(() => { const el = scrollElementRef.current; if (!isInverted || !el || isEditing) return undefined; + const invertScrollWheel = (e: WheelEvent) => { el.scrollTop -= e.deltaY; e.preventDefault(); diff --git a/apps/tlon-web/src/state/channel/channel.ts b/apps/tlon-web/src/state/channel/channel.ts index 4fa5e42426..d8e166cc5a 100644 --- a/apps/tlon-web/src/state/channel/channel.ts +++ b/apps/tlon-web/src/state/channel/channel.ts @@ -864,7 +864,7 @@ export function useChannelsFirehose() { useEffect(() => { api.subscribe({ app: 'channels', - path: '/', + path: '/v1', event: eventHandler, }); }, [eventHandler]); @@ -956,7 +956,7 @@ export function usePost(nest: Nest, postId: string, disabled = false) { [nest, postId] ); - const subPath = useMemo(() => `/${nest}`, [nest]); + const subPath = useMemo(() => `/v1/${nest}`, [nest]); const enabled = useMemo( () => postId !== '0' && postId !== '' && nest !== '' && !disabled, diff --git a/desk/desk.docket-0 b/desk/desk.docket-0 index 9400eb46f9..546ed19ff1 100644 --- a/desk/desk.docket-0 +++ b/desk/desk.docket-0 @@ -2,7 +2,7 @@ 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-0vr2id1.vlmom.gq3nb.6l916.f3rr8.glob' 0vr2id1.vlmom.gq3nb.6l916.f3rr8] + glob-http+['https://bootstrap.urbit.org/glob-0v5.j8ncr.g5anp.8l14l.61k9v.p1n44.glob' 0v5.j8ncr.g5anp.8l14l.61k9v.p1n44] base+'groups' version+[5 7 0] website+'https://tlon.io' diff --git a/package-lock.json b/package-lock.json index 50f844f070..93ae77ede4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -44,6 +44,7 @@ "expo-asset": "~9.0.2", "expo-clipboard": "~5.0.1", "expo-constants": "~15.4.5", + "expo-dev-client": "^3.3.9", "expo-device": "~5.9.3", "expo-file-system": "~16.0.6", "expo-localization": "~14.8.3", @@ -24005,6 +24006,104 @@ "expo": "*" } }, + "node_modules/expo-dev-client": { + "version": "3.3.9", + "resolved": "https://registry.npmjs.org/expo-dev-client/-/expo-dev-client-3.3.9.tgz", + "integrity": "sha512-qODvuyXe8FgVJhBbwDEk/snZa5wSTNHx+poNXwA/PS4gGvOxCuG+qpeQF6K4Yf6r2+sV0OtigxPJiAyhu9I4ug==", + "dependencies": { + "expo-dev-launcher": "3.6.7", + "expo-dev-menu": "4.5.6", + "expo-dev-menu-interface": "1.7.2", + "expo-manifests": "~0.13.0", + "expo-updates-interface": "~0.15.1" + }, + "peerDependencies": { + "expo": "*" + } + }, + "node_modules/expo-dev-launcher": { + "version": "3.6.7", + "resolved": "https://registry.npmjs.org/expo-dev-launcher/-/expo-dev-launcher-3.6.7.tgz", + "integrity": "sha512-xn0cq2LMXv5t3n4jiAPFd9rwP22GM3zsQqAOJuWXH4b7fRzO8bayxOAt1n4RrDgkVsRzgRnxHm7kkO+Eta3Kzg==", + "dependencies": { + "ajv": "8.11.0", + "expo-dev-menu": "4.5.6", + "expo-manifests": "~0.13.0", + "resolve-from": "^5.0.0", + "semver": "^7.5.3" + }, + "peerDependencies": { + "expo": "*" + } + }, + "node_modules/expo-dev-launcher/node_modules/ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/expo-dev-launcher/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "node_modules/expo-dev-launcher/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/expo-dev-menu": { + "version": "4.5.6", + "resolved": "https://registry.npmjs.org/expo-dev-menu/-/expo-dev-menu-4.5.6.tgz", + "integrity": "sha512-V8gOFrv8JBTy50n9mTWVPKVHMcjvrpI/w5ooZGFzjoerBlPXSauIfRmHsqmgmOr3r5oWptnC2PS3LxuSo4QZ5g==", + "dependencies": { + "expo-dev-menu-interface": "1.7.2", + "semver": "^7.5.3" + }, + "peerDependencies": { + "expo": "*" + } + }, + "node_modules/expo-dev-menu-interface": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/expo-dev-menu-interface/-/expo-dev-menu-interface-1.7.2.tgz", + "integrity": "sha512-V/geSB9rW0IPTR+d7E5CcvkV0uVUCE7SMHZqE/J0/dH06Wo8AahB16fimXeh5/hTL2Qztq8CQ41xpFUBoA9TEw==", + "peerDependencies": { + "expo": "*" + } + }, + "node_modules/expo-dev-menu/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/expo-device": { "version": "5.9.3", "resolved": "https://registry.npmjs.org/expo-device/-/expo-device-5.9.3.tgz", @@ -36187,7 +36286,6 @@ }, "node_modules/uri-js": { "version": "4.4.1", - "dev": true, "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0"