Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
164 changes: 164 additions & 0 deletions MOBILE_CONNECTION_RUNBOOK.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
# Conexão móvel do T3 Code

Este documento registra o setup usado para conectar o celular e o tablet Android ao T3 Code no
Linux e no Mac. Ele não contém tokens: as credenciais de pareamento são temporárias e devem ser
geradas novamente para cada aplicativo e dispositivo.

## Configuração atual

| Máquina | Endereço Tailscale HTTPS | IP do tailnet |
| --------- | ----------------------------------------------- | --------------- |
| Linux MSI | `https://gabriel-alonso-msi.tailad333c.ts.net` | `100.70.132.45` |
| Mac mini | `https://mac-mini-de-gabriel.tailad333c.ts.net` | `100.71.185.10` |

O Tailscale precisa permanecer conectado no dispositivo móvel, inclusive dentro de casa. Sem exit
node habilitado, somente o tráfego destinado ao tailnet passa pelo Tailscale. No Wi-Fi de casa, a
comunicação entre os pares normalmente continua direta pela rede local.

Aplicativos Android:

| Aplicativo | Package ID | APK |
| ----------------------- | ------------------------ | ------------------------------------------------------------------------- |
| React Native standalone | `com.t3tools.t3code.dev` | `apps/mobile/android/app/build/outputs/apk/release/app-release.apk` |
| Capacitor | `tools.t3code.mobile` | `apps/mobile-capacitor/android/app/build/outputs/apk/debug/app-debug.apk` |

Dispositivos usados no setup:

| Dispositivo | Modelo | Último serial ADB conhecido |
| ----------- | ---------------- | --------------------------- |
| Celular | Samsung SM-S928B | `RXCX800G1DY` |
| Tablet | Samsung SM-X610 | `RX2XC0094TX` |

Sempre confirme o serial atual antes de executar comandos:

```bash
ADB="$HOME/.local/share/Android/Sdk/platform-tools/adb"
"$ADB" devices -l
```

## Verificação das máquinas

No Linux:

```bash
tailscale status
tailscale serve status
```

O Tailscale Serve do Linux deve encaminhar o HTTPS para o servidor local:

```text
https://gabriel-alonso-msi.tailad333c.ts.net/ -> http://127.0.0.1:3773
```

No Mac:

```bash
ssh mac-mini '/Applications/Tailscale.app/Contents/MacOS/Tailscale status; \
/Applications/Tailscale.app/Contents/MacOS/Tailscale serve status'
```

O T3 Code precisa estar em execução nas duas máquinas antes de testar o aplicativo.

## Gerar credenciais de pareamento

Gere uma credencial diferente para cada combinação de dispositivo e aplicativo. O exemplo abaixo
cria uma credencial de 30 minutos para o Linux:

```bash
npx --yes t3@0.0.28 auth pairing create \
--base-dir "$HOME/.t3" \
--ttl 30m \
--label "NOME DO DISPOSITIVO E APLICATIVO" \
--base-url "https://gabriel-alonso-msi.tailad333c.ts.net" \
--json
```

Para o Mac:

```bash
ssh mac-mini 'PATH=/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:$PATH; \
/opt/homebrew/bin/npx --yes t3@0.0.28 auth pairing create \
--base-dir "$HOME/.t3" \
--ttl 30m \
--label "NOME DO DISPOSITIVO E APLICATIVO" \
--base-url "https://mac-mini-de-gabriel.tailad333c.ts.net" \
--json'
```

Use o campo `credential` retornado como código de pareamento. Não registre esse código neste
documento.

## Parear os aplicativos

No React Native:

1. Abra **Settings → Environments → +**.
2. Informe o endereço HTTPS da máquina e o `credential` correspondente.
3. Repita para a outra máquina.
4. Confirme que os dois ambientes aparecem como **Connected**.

No Capacitor:

1. Abra **Settings → Connections → Add environment**.
2. Informe o endereço HTTPS da máquina e o `credential` correspondente.
3. Repita para a outra máquina.
4. Confirme os dois indicadores verdes.

## Compilar e instalar

### Capacitor

```bash
vp run --filter @t3tools/mobile-capacitor build

cd apps/mobile-capacitor/android
ANDROID_HOME="$HOME/.local/share/Android/Sdk" \
ANDROID_SDK_ROOT="$HOME/.local/share/Android/Sdk" \
./gradlew app:assembleDebug --no-daemon
```

Instalação preservando os pareamentos existentes:

```bash
ADB="$HOME/.local/share/Android/Sdk/platform-tools/adb"
"$ADB" -s SERIAL install -r \
apps/mobile-capacitor/android/app/build/outputs/apk/debug/app-debug.apk
```

Se aparecer `INSTALL_FAILED_UPDATE_INCOMPATIBLE`, existe uma versão antiga assinada por outra
chave. A substituição abaixo apaga somente os dados do Capacitor e exige novo pareamento:

```bash
"$ADB" -s SERIAL uninstall tools.t3code.mobile
"$ADB" -s SERIAL install \
apps/mobile-capacitor/android/app/build/outputs/apk/debug/app-debug.apk
```

### React Native standalone

```bash
cd apps/mobile/android
ANDROID_HOME="$HOME/.local/share/Android/Sdk" \
ANDROID_SDK_ROOT="$HOME/.local/share/Android/Sdk" \
./gradlew app:assembleRelease --no-daemon
```

```bash
ADB="$HOME/.local/share/Android/Sdk/platform-tools/adb"
"$ADB" -s SERIAL install -r \
apps/mobile/android/app/build/outputs/apk/release/app-release.apk
```

Use o APK `release`: o APK de desenvolvimento depende do Metro e não é adequado para uso longe do
computador.

## Checklist final

- Tailscale conectado no Linux, Mac e dispositivo Android.
- T3 Code em execução nas duas máquinas.
- Linux e Mac aparecem como **Connected** nos dois aplicativos.
- Threads das duas máquinas são carregadas.
- O React Native abre sem Metro e sem cabo USB.
- O Capacitor respeita as barras de status e navegação em retrato e paisagem.
- `vp check`, `vp run typecheck` e `vp run lint:mobile` passam antes de distribuir novos APKs.
15 changes: 15 additions & 0 deletions apps/mobile-capacitor/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# T3 Code Mobile — Capacitor

Shell Android do `apps/web`, separado do aplicativo React Native em `apps/mobile`.

O shell usa o runtime moderno de conexões do web app. Assim, o celular pode salvar
vários ambientes (por exemplo, Linux e Mac via Tailscale), mantendo apenas o ambiente
selecionado ativo.

```bash
vp run --filter @t3tools/mobile-capacitor build
vp run --filter @t3tools/mobile-capacitor open:android
```

O Android permite HTTP sem TLS para endereços privados/Tailscale. A autenticação
continua obrigatória: cada máquina precisa ser pareada para emitir seu bearer token.
101 changes: 101 additions & 0 deletions apps/mobile-capacitor/android/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Using Android gitignore template: https://github.com/github/gitignore/blob/HEAD/Android.gitignore

# Built application files
*.apk
*.aar
*.ap_
*.aab

# Files for the ART/Dalvik VM
*.dex

# Java class files
*.class

# Generated files
bin/
gen/
out/
# Uncomment the following line in case you need and you don't have the release build type files in your app
# release/

# Gradle files
.gradle/
build/

# Local configuration file (sdk path, etc)
local.properties

# Proguard folder generated by Eclipse
proguard/

# Log Files
*.log

# Android Studio Navigation editor temp files
.navigation/

# Android Studio captures folder
captures/

# IntelliJ
*.iml
.idea/workspace.xml
.idea/tasks.xml
.idea/gradle.xml
.idea/assetWizardSettings.xml
.idea/dictionaries
.idea/libraries
# Android Studio 3 in .gitignore file.
.idea/caches
.idea/modules.xml
# Comment next line if keeping position of elements in Navigation Editor is relevant for you
.idea/navEditor.xml

# Keystore files
# Uncomment the following lines if you do not want to check your keystore files in.
#*.jks
#*.keystore

# External native build folder generated in Android Studio 2.2 and later
.externalNativeBuild
.cxx/

# Google Services (e.g. APIs or Firebase)
# google-services.json

# Freeline
freeline.py
freeline/
freeline_project_description.json

# fastlane
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots
fastlane/test_output
fastlane/readme.md

# Version control
vcs.xml

# lint
lint/intermediates/
lint/generated/
lint/outputs/
lint/tmp/
# lint/reports/

# Android Profiling
*.hprof

# Cordova plugins for Capacitor
capacitor-cordova-android-plugins

# Copied web assets
app/src/main/assets/public

# Generated Config files
app/src/main/assets/capacitor.config.json
app/src/main/assets/capacitor.plugins.json
app/src/main/res/xml/config.xml
2 changes: 2 additions & 0 deletions apps/mobile-capacitor/android/app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/build/*
!/build/.npmkeep
54 changes: 54 additions & 0 deletions apps/mobile-capacitor/android/app/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
apply plugin: 'com.android.application'

android {
namespace = "tools.t3code.mobile"
compileSdk = rootProject.ext.compileSdkVersion
defaultConfig {
applicationId "tools.t3code.mobile"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
aaptOptions {
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
// Default: https://android.googlesource.com/platform/frameworks/base/+/282e181b58cf72b6ca770dc7ca5f91f135444502/tools/aapt/AaptAssets.cpp#61
ignoreAssetsPattern = '!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~'
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}

repositories {
flatDir{
dirs '../capacitor-cordova-android-plugins/src/main/libs', 'libs'
}
}

dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
implementation "androidx.coordinatorlayout:coordinatorlayout:$androidxCoordinatorLayoutVersion"
implementation "androidx.core:core-splashscreen:$coreSplashScreenVersion"
implementation project(':capacitor-android')
testImplementation "junit:junit:$junitVersion"
androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
implementation project(':capacitor-cordova-android-plugins')
}

apply from: 'capacitor.build.gradle'

try {
def servicesJSON = file('google-services.json')
if (servicesJSON.text) {
apply plugin: 'com.google.gms.google-services'
}
} catch(Exception e) {
logger.info("google-services.json not found, google-services plugin not applied. Push Notifications won't work")
}
19 changes: 19 additions & 0 deletions apps/mobile-capacitor/android/app/capacitor.build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN

android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_21
targetCompatibility JavaVersion.VERSION_21
}
}

apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle"
dependencies {


}


if (hasProperty('postBuildExtras')) {
postBuildExtras()
}
21 changes: 21 additions & 0 deletions apps/mobile-capacitor/android/app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
Loading
Loading