diff --git a/docs/.gitbook/assets/android_logo.png b/docs/.gitbook/assets/android_logo.png new file mode 100644 index 000000000..bde140892 Binary files /dev/null and b/docs/.gitbook/assets/android_logo.png differ diff --git a/docs/.gitbook/assets/android_theme_1.png b/docs/.gitbook/assets/android_theme_1.png new file mode 100644 index 000000000..68c5b3071 Binary files /dev/null and b/docs/.gitbook/assets/android_theme_1.png differ diff --git a/docs/.gitbook/assets/android_theme_2.png b/docs/.gitbook/assets/android_theme_2.png new file mode 100644 index 000000000..646688913 Binary files /dev/null and b/docs/.gitbook/assets/android_theme_2.png differ diff --git a/docs/.gitbook/assets/android_theme_3.png b/docs/.gitbook/assets/android_theme_3.png new file mode 100644 index 000000000..bcf303249 Binary files /dev/null and b/docs/.gitbook/assets/android_theme_3.png differ diff --git a/docs/ui-components/seam-mobile-components/README.md b/docs/ui-components/seam-mobile-components/README.md index 81c2798a0..b606e53b7 100644 --- a/docs/ui-components/seam-mobile-components/README.md +++ b/docs/ui-components/seam-mobile-components/README.md @@ -24,5 +24,40 @@ Seam Mobile Components are pre-built views that let you deliver end-user access ### Platform Guides -
Cover image
iOS Guide
Integrate Seam Mobile Components into your iOS app
image (35).pngseam-mobile-components-for-ios

Android Guide

Coming soon!

image (32).png
+ + + + + + + + + + + + + + + + + + + + +
+ Cover image
+ iOS Guide +
Integrate Seam Mobile Components into your iOS app +
+ image (35).png + + seam-mobile-components-for-ios +
+ Android Guide +
Integrate Seam Mobile Components into your Android app +
+ android_logo.png + + seam-mobile-components-for-android +
diff --git a/docs/ui-components/seam-mobile-components/seam-mobile-components-for-android/README.md b/docs/ui-components/seam-mobile-components/seam-mobile-components-for-android/README.md new file mode 100644 index 000000000..33c17c51d --- /dev/null +++ b/docs/ui-components/seam-mobile-components/seam-mobile-components-for-android/README.md @@ -0,0 +1,276 @@ +--- +description: >- + Learn how to set up Seam Mobile Components in your Android project using GitHub + Packages, drop in SeamAccessView for a complete unlock flow, and + customize the look with SeamComponentsTheme. +--- + +# Seam Mobile Components for Android + +#### Prerequisites + +* **Compile SDK:** 35 +* **Kotlin Version:** 2.1.0 or greater +* **Minimum Android SDK:** The required `minSdk` depends on the specific Seam integration modules you include: + * Base SDK (Core, API, Common, Network, Analytics): **API Level 24** (Android 7.0) + * Including `saltoks` or `saltospace`: **API Level 24** (Android 7.0) + * Including `latch`: **API Level 26** (Android 8.0) + * Including `assaabloy`: **API Level 28** (Android 9.0) + + Your application's `minSdk` must be set to the **highest** level required by any of the Seam modules you use. + + +You should already have a Seam workspace and API key set up. If you’re new to Seam, start with the [Seam Mobile SDK](https://docs.seam.co/latest/developer-tools/mobile-sdks/android-sdk). + +*** + +### Installation + +Setup your project to get the Android SDK Packages form GitHub, as described [here](https://docs.seam.co/latest/capability-guides/mobile-access/mobile-device-sdks/initializing-the-seam-mobile-sdk). + +Add the Seam Components library and required SDK modules to your app's `build.gradle.kts` (or `build.gradle` for Groovy): + +**Kotlin DSL (`build.gradle.kts`):** +```kotlin +dependencies { + val seamVersion = "3.1.1" // Check for latest version + + // Required: Seam Components UI library + implementation("co.seam:seam-phone-sdk-android-seamcomponents:$seamVersion") + + // Required: Core SDK functionality + implementation("co.seam:seam-phone-sdk-android-core:$seamVersion") + + // Optional: Add integration modules as needed based on your lock providers + implementation("co.seam:seam-phone-sdk-android-assaabloy:$seamVersion") // minSdk 28 + implementation("co.seam:seam-phone-sdk-android-latch:$seamVersion") // minSdk 26 + implementation("co.seam:seam-phone-sdk-android-saltoks:$seamVersion") // minSdk 24 + implementation("co.seam:seam-phone-sdk-android-saltospace:$seamVersion") // minSdk 24 +} +``` + +**Groovy (`build.gradle`):** +```groovy +dependencies { + def seamVersion = "3.1.1" // Check for latest version + + // Required: Seam Components UI library + implementation "co.seam:seam-phone-sdk-android-seamcomponents:$seamVersion" + + // Required: Core SDK functionality + implementation "co.seam:seam-phone-sdk-android-core:$seamVersion" + + // Optional: Add integration modules as needed + implementation "co.seam:seam-phone-sdk-android-assaabloy:$seamVersion" // minSdk 28 + implementation "co.seam:seam-phone-sdk-android-latch:$seamVersion" // minSdk 26 + implementation "co.seam:seam-phone-sdk-android-saltoks:$seamVersion" // minSdk 24 + implementation "co.seam:seam-phone-sdk-android-saltospace:$seamVersion" // minSdk 24 +} +``` + +### Quick Start: `SeamAccessView` + +### Quick Start - Complete Integration + +#### SeamAccessView - Your Complete Solution + +`SeamAccessView` is the main entry point composable for the Seam access management interface. This powerful component manages the entire user flow for accessing and managing credentials through the Seam SDK, making it the perfect choice for most applications. + +**What SeamAccessView handles for you:** +- **SDK Initialization**: Automatically initializes the Seam SDK with your session token +- **Navigation Management**: Handles screen transitions and navigation state +- **UI State Management**: Manages loading, error handling, and different application states +- **OTP Authorization**: Automatically handles OTP verification flows when required +- **Bluetooth Permissions**: Guides users through Bluetooth setup when needed for credential operations + +**Screen Orchestration:** +SeamAccessView automatically navigates between these screens based on application state: +- **Credentials List Screen**: For viewing available keys with pull-to-refresh functionality +- **OTP Authorization Screen**: For completing authentication flows in a WebView +- **Bluetooth Redirect Screen**: For handling Bluetooth permission and setup +- **Unlock Overlay**: For interacting with individual credentials through a modal interface + +#### Basic Usage + +For most use cases, you can use `SeamAccessView` as a complete solution: + +```kotlin +@Composable +fun MyApp() { + MyAppTheme { + SeamAccessView( + clientSessionToken = "your-session-token-here" + ) + } +} +``` + +#### With Custom Navigation + +If you need more control over navigation or want to integrate with your existing navigation setup: + +```kotlin +@Composable +fun MyApp() { + val navController = rememberNavController() + + MyAppTheme { + SeamAccessView( + clientSessionToken = "your-session-token-here", + context = LocalContext.current, + navController = navController + ) + } +} +``` + +**Parameters:** +- `clientSessionToken`: Required session token for SDK authentication and initialization +- `context`: Android context (defaults to current composition's local context) +- `navController`: Navigation controller for screen transitions (defaults to a new instance) + +### Initialization & Authentication + +#### Client Session Token (CST) Management + +Client Session Tokens authenticate your mobile app with Seam's backend. These tokens should be generated by your backend server using Seam's API. + +#### Obtaining a CST +Ask Seam about how to obtain a CST. +For more details see [Seam's Client Session Token documentation](https://docs.seam.co/latest/core-concepts/authentication/client-session-tokens). + + +#### SDK Initialization + +When using individual components instead of `SeamAccessView`, you must manually initialize the Seam SDK: + +```kotlin +@Composable +fun MyCredentialsScreen(clientSessionToken: String) { + val context = LocalContext.current + + LaunchedEffect(clientSessionToken) { + try { + // Initialize the SDK. This part is usually done in a ViewModel + SeamSDK.initialize( + context = context, + clientSessionToken = clientSessionToken + ) + + // Activate the SDK after initialization + SeamSDK.getInstance().activate() + } catch (error: SeamError) { + // handle error + } + } + + SeamCredentialsView( + onNavigateToUnlock = { /* Handle navigation */ } + ) +} +``` + +### Screen Components + +When you need more granular control than `SeamAccessView` provides, you can use individual screen components to build custom flows while still benefiting from Seam's pre-built UI. + +#### SeamCredentialsView + +**What it does:** A composable screen that displays cards for user credentials (keys) with comprehensive state management and user interaction support. + +**Key Features:** +- **State Management**: Automatically handles loading, success with data, and empty states +- **Pull-to-Refresh**: Built-in refresh functionality for updating credential data +- **Error Handling**: Displays appropriate user feedback for error states +- **Navigation Integration**: Provides callback for seamless navigation to unlock interfaces +- **Internet Status**: Shows connection status and handles offline scenarios + +**When to use:** When you want a complete credentials listing screen but need to customize the navigation or integrate with your own view models and navigation system. + +```kotlin +@Composable +fun CredentialsScreen() { + // viewModel is optional + val viewModel: KeysViewModel = viewModel() + + // Remember to initialize the SDK before using the view. See previous section for details. + SeamCredentialsView( + viewModel = viewModel, + onNavigateToUnlock = { keyCard -> + // Navigate to unlock screen + println("Unlocking key: ${keyCard.name}") + } + ) +} +``` + +#### SeamUnlockCardView + +**What it does:** A modal bottom sheet composable that provides a complete user interface for unlocking credentials with phase-based state management. + +**Key Features:** +- **Modal Presentation**: Displays as an overlay bottom sheet that doesn't disrupt the main UI +- **Unlock Phases**: Manages different states (idle, scanning, success, failed) with appropriate UI feedback +- **Theme Integration**: Supports customization through SeamUnlockCardStyle theming +- **Automatic State Reset**: Handles cleanup when dismissed or navigation occurs +- **Error Recovery**: Built-in error states with retry functionality + +**When to use:** When you want to provide unlock functionality in a modal format, either triggered from your custom credential list or integrated into your own navigation flow. + +```kotlin +@Composable +fun UnlockModal(keyCard: KeyCard) { + + val viewModel: KeysViewModel = viewModel() + + var showUnlock by remember { mutableStateOf(false) } + var selectedKeyCard by remember { mutableStateOf(null) } + + // Remember to initialize the SDK before using the view. See previous section for details. + SeamCredentialsView( + viewModel = viewModel, + onNavigateToUnlock = { keyCard -> + // Navigate to unlock screen + selectedKeyCard = keyCard + showUnlock = true + } + ) + + // The simplest way to use the unlock view is to call it on `onNavigateToUnlock` + // callback from `SeamCredentialsView`, as it already provides the keyCard + + SeamUnlockCardView( + keyCard = keyCard, + onNavigateBack = { showUnlock = false } + ) +} +``` + +#### SeamOtpView + +**What it does:** A full-screen dialog composable that displays an OTP (One-Time Password) verification interface using a WebView for interactive authentication flows. + +**Key Features:** +- **Full-Screen Presentation**: Renders as a dialog that overlays the host app's UI completely +- **WebView Integration**: Handles OTP verification flows with JavaScript enabled for interactivity +- **Custom Navigation**: Includes a styled top bar with back navigation controls +- **URL Handling**: Loads the provided OTP URL and manages the verification process +- **Dialog Management**: Proper dismissal handling that integrates with your app's navigation + +**When to use:** When your authentication flow requires OTP verification and you want a seamless, full-screen experience that doesn't disrupt your main app navigation. + +```kotlin +@Composable +fun OtpScreen() { + SeamOtpView( + otpUrl = "https://example.com/otp-verification", + onNavigateBack = { + // Handle navigation back + } + ) +} +``` + +#### See Also + +* Explore [Seam Mobile SDK](https://docs.seam.co/latest/developer-tools/mobile-sdks/android-sdk) diff --git a/docs/ui-components/seam-mobile-components/seam-mobile-components-for-android/theming/README.md b/docs/ui-components/seam-mobile-components/seam-mobile-components-for-android/theming/README.md new file mode 100644 index 000000000..4947aa4bf --- /dev/null +++ b/docs/ui-components/seam-mobile-components/seam-mobile-components-for-android/theming/README.md @@ -0,0 +1,51 @@ +--- +description: >- + Theming — Apply your brand’s colors, fonts, and styles to Seam Mobile + Components with SeamComponentsTheme. +--- + +# Theming + + +
+ +Seam Mobile Components are fully customizable using Material 3 theming integrated with Seam's component-specific styling system. You can customize colors, typography, and detailed component styles to match your brand. + +*** + +### How theming works + +The simplest way to theme Seam components is to use `SeamComponentsTheme` with your Material 3 color schemes: + +```kotlin +@Composable +fun MyApp() { + val lightColors = lightColorScheme( + primary = Color(0xFF1976D2), + onPrimary = Color.White, + secondary = Color(0xFF757575), + onSecondary = Color.White, + background = Color.White, + onBackground = Color(0xFF212121) + ) + + val darkColors = darkColorScheme( + primary = Color(0xFF90CAF9), + onPrimary = Color(0xFF003C7E), + secondary = Color(0xFF424242), + onSecondary = Color.White, + background = Color(0xFF121212), + onBackground = Color.White + ) + + val colorScheme = if (isSystemInDarkTheme()) darkColors else lightColors + + SeamComponentsTheme( + colorScheme = colorScheme + ) { + SeamAccessView( + clientSessionToken = "your-token" + ) + } +} +``` diff --git a/docs/ui-components/seam-mobile-components/seam-mobile-components-for-android/theming/colors.md b/docs/ui-components/seam-mobile-components/seam-mobile-components-for-android/theming/colors.md new file mode 100644 index 000000000..d5cad6680 --- /dev/null +++ b/docs/ui-components/seam-mobile-components/seam-mobile-components-for-android/theming/colors.md @@ -0,0 +1,111 @@ +--- +description: >- + Define semantic colors for text, backgrounds, states, and accents +--- + +# Colors + +Use Material 3 to customize colors. Here is a suggestion of how to customize your app colors. + +### Define a data class to hold the colors values: +{% code title="AppColors.kt" %} +```kotlin +data class AppColors( + val background: Color, + val headerBackground: Color, + val accentColor: Color, + val accentColorLight: Color, + val textColor: Color, + val textInvert: Color, + val iconIdleColor: Color, + val iconActiveColor: Color , + val successColor: Color, + val errorColor: Color, + val buttonGradient: List, + val cardBackgroundGradient: List, +) +``` +{% endcode %} + +### Create instances of `AppColors` for light and dark modes: + +{% code title="ColorConstants.kt" %} +```kotlin +// +val lightAppColors = AppColors( + background = Color(0xFFF8FAFC), + headerBackground = Color(0xFFDADCDE), + accentColor = Color(0xFF334155), + accentColorLight = Color(0xFF1F2D41), + textColor = Color(0xFF334155), + textInvert = Color(0xFFF8FAFC), + iconIdleColor = Color(0xFFFFFFFF), + iconActiveColor = Color(0xFF334155), + successColor = Color(0xFF059669), + errorColor = Color(0xFFDC2626), + buttonGradient = listOf(Color(0xFF334155), Color(0xFF1F2D41)), + cardBackgroundGradient = listOf(Color(0xFFE4E8EF), Color(0xFFEEF2F9)) +) + +val darkAppColors = AppColors( + background = Color(0xFF0F172A), + headerBackground = Color(0xFF1E293B), + accentColor = Color(0xFF64748B), + accentColorLight = Color(0xFF94A3B8), + textColor = Color(0xFFE2E8F0), + textInvert = Color(0xFF0F172A), + iconIdleColor = Color(0xFF475569), + iconActiveColor = Color(0xFFE2E8F0), + successColor = Color(0xFF10B981), + errorColor = Color(0xFFEF4444), + buttonGradient = listOf(Color(0xFF475569), Color(0xFF64748B)), + cardBackgroundGradient = listOf(Color(0xFF1E293B), Color(0xFF334155)) +) +``` +{% endcode %} + +### Set the color scheme to `SeamComponentsTheme` + +{% code title="MainActivity.kt" %} +```kotlin +@Composable +fun MyApp() { + // Check if is in dark theme + val darkTheme = isSystemInDarkTheme() + // get AppColors for light or dark mode + val appColors = when { + darkTheme -> darkAppColors + else -> lightAppColors + } + + // Create the color scheme + val colorScheme = when { + darkTheme -> darkColorScheme( + primary = appColors.accentColor, + onPrimary = appColors.textInvert, + onSurface = appColors.textColor, + background = appColors.background, + secondary = appColors.background, + onSecondary = appColors.textColor, + ) + else -> lightColorScheme( + primary = appColors.accentColor, + onPrimary = appColors.textInvert, + onSurface = appColors.textColor, + background = appColors.background, + secondary = appColors.background, + onSecondary = appColors.textColor, + ) + } + + // Set the color scheme + SeamComponentsTheme( + colorScheme = colorScheme + ) { + SeamAccessView( + clientSessionToken = "your-token" + ) + } +} +``` +{% endcode %} \ No newline at end of file diff --git a/docs/ui-components/seam-mobile-components/seam-mobile-components-for-android/theming/fonts.md b/docs/ui-components/seam-mobile-components/seam-mobile-components-for-android/theming/fonts.md new file mode 100644 index 000000000..b4d8bbbf7 --- /dev/null +++ b/docs/ui-components/seam-mobile-components/seam-mobile-components-for-android/theming/fonts.md @@ -0,0 +1,43 @@ +--- +description: Set typography roles with Material 3 Typography. +--- + +### Custom Typography Integration + +You can integrate custom typography with Material 3's typography system: + +{% code title="MainActivity.kt" %} +```kotlin +@Composable +fun MyApp() { + val customTypography = Typography( + headlineLarge = TextStyle( + fontFamily = FontFamily.Serif, + fontWeight = FontWeight.Bold, + fontSize = 32.sp + ), + bodyLarge = TextStyle( + fontFamily = FontFamily.SansSerif, + fontWeight = FontWeight.Normal, + fontSize = 16.sp + ), + labelMedium = TextStyle( + fontFamily = FontFamily.Monospace, + fontWeight = FontWeight.Medium, + fontSize = 12.sp, + letterSpacing = 0.5.sp + ) + ) + + // Set the custom typography + SeamComponentsTheme( + typography = customTypography, + colorScheme = colorScheme + ) { + SeamAccessView( + clientSessionToken = "your-token" + ) + } +} +``` +{% endcode %} \ No newline at end of file diff --git a/docs/ui-components/seam-mobile-components/seam-mobile-components-for-android/theming/keycard-styles.md b/docs/ui-components/seam-mobile-components/seam-mobile-components-for-android/theming/keycard-styles.md new file mode 100644 index 000000000..24bee7b35 --- /dev/null +++ b/docs/ui-components/seam-mobile-components/seam-mobile-components-for-android/theming/keycard-styles.md @@ -0,0 +1,88 @@ +--- +description: >- + Style key card components with custom gradients, logos, corner radius, and + shadows. +--- + +# Keycard styles + +Controls the look of key card UI (background gradient, logo, shadow, corner radius, etc.). + +```kotlin +data class SeamKeyCardStyle( + val brandLogoUrl: String? = null, + @DrawableRes val brandLogoRes: Int? = null, + @DrawableRes val backgroundTextureRes: Int? = null, + val textColor: Color? = null, + val backgroundGradient: List? = null, + val errorColor: Color? = null, + val accentColor: Color? = null, + val headerLogoTint: Color? = null, + val cornerRadius: Dp? = null, + val shadowColor: Color? = null, + val shadowYOffset: Dp? = null, +) +``` + +#### Examples: + +Check [colors](./colors.md) section to understand how to create `darkAppColors` and `lightAppColors` objects. + +{% code title="MainActivity.kt" %} +```kotlin +@Composable +fun MyApp() { + // Check if is in dark theme + val darkTheme = isSystemInDarkTheme() + // get AppColors for light or dark mode + val appColors = when { + darkTheme -> darkAppColors + else -> lightAppColors + } + + // Create the color scheme + val colorScheme = when { + darkTheme -> darkColorScheme( + primary = appColors.accentColor, + onPrimary = appColors.textInvert, + onSurface = appColors.textColor, + background = appColors.background, + secondary = appColors.background, + onSecondary = appColors.textColor, + ) + else -> lightColorScheme( + primary = appColors.accentColor, + onPrimary = appColors.textInvert, + onSurface = appColors.textColor, + background = appColors.background, + secondary = appColors.background, + onSecondary = appColors.textColor, + ) + } + + // Create the SeamKeyCardStyle object + val keyCardStyle = SeamKeyCardStyle( + backgroundGradient = appColors.cardBackgroundGradient, + accentColor = appColors.accentColor, + textColor = appColors.textColor, + headerLogoTint = appColors.iconActiveColor, + cornerRadius = 16.dp, + ) + + // Create a SeamTheme with keyCardStyle as a parameter + val seamTheme = SeamTheme( + keyCard = keyCardStyle, + ) + + // Set the seamTheme to SeamComponentsTheme + SeamComponentsTheme( + seamTheme = seamTheme, + colorScheme = colorScheme + ) { + SeamAccessView( + clientSessionToken = "your-token" + ) + } +} +``` +{% endcode %} diff --git a/docs/ui-components/seam-mobile-components/seam-mobile-components-for-android/theming/unlockcard-styles.md b/docs/ui-components/seam-mobile-components/seam-mobile-components-for-android/theming/unlockcard-styles.md new file mode 100644 index 000000000..5274317eb --- /dev/null +++ b/docs/ui-components/seam-mobile-components/seam-mobile-components-for-android/theming/unlockcard-styles.md @@ -0,0 +1,111 @@ +--- +description: >- + Control unlock card appearance, including header, key button, progress, + instructions, and status states. +--- + +# UnlockCard styles + +Used by `SeamUnlockCardView` and related UI (container, header, key button, progress, instructions, status colors). + +```kotlin +data class SeamUnlockCardStyle( + val cardBackground: Color? = null, + val headerBackground: Color? = null, + val headerTitleColor: Color? = null, + val headerSubtitleColor: Color? = null, + val keyIconColorIdle: Color? = null, + val keyIconColorActive: Color? = null, + val keyButtonGradient: List? = null, + val keyButtonShadowRadius: Dp? = null, + val instructionTextColor: Color? = null, + val bulletBackground: Color? = null, + val bulletTextColor: Color? = null, + val successColor: Color? = null, + val successIconColor: Color? = null, + val errorColor: Color? = null, +) +``` + +#### Examples: + +Check [colors](./colors.md) section to understand how to create `darkAppColors` and `lightAppColors` objects. + +{% code title="MainActivity.kt" %} +```kotlin +@Composable +fun MyApp() { + // Check if is in dark theme + val darkTheme = isSystemInDarkTheme() + // get AppColors for light or dark mode + val appColors = when { + darkTheme -> darkAppColors + else -> lightAppColors + } + + // Create the color scheme + val colorScheme = when { + darkTheme -> darkColorScheme( + primary = appColors.accentColor, + onPrimary = appColors.textInvert, + onSurface = appColors.textColor, + background = appColors.background, + secondary = appColors.background, + onSecondary = appColors.textColor, + ) + else -> lightColorScheme( + primary = appColors.accentColor, + onPrimary = appColors.textInvert, + onSurface = appColors.textColor, + background = appColors.background, + secondary = appColors.background, + onSecondary = appColors.textColor, + ) + } + + // Create the SeamKeyCardStyle object + val keyCardStyle = SeamKeyCardStyle( + backgroundGradient = appColors.cardBackgroundGradient, + accentColor = appColors.accentColor, + textColor = appColors.textColor, + headerLogoTint = appColors.iconActiveColor, + cornerRadius = 16.dp, + ) + + // Define Unlock Card Style + val unlockCardStyle = SeamUnlockCardStyle( + keyButtonGradient = appColors.buttonGradient, + keyButtonShadowRadius = 12.dp, + bulletBackground = appColors.accentColor, + bulletTextColor = appColors.textInvert, + instructionTextColor = appColors.textColor, + headerBackground = appColors.headerBackground, + headerTitleColor = appColors.textColor, + headerSubtitleColor = appColors.textColor, + keyIconColorIdle = appColors.iconIdleColor, + keyIconColorActive = appColors.iconActiveColor, + successColor = appColors.successColor, + successIconColor = appColors.textInvert, + errorColor = appColors.errorColor, + ) + + // Create a SeamTheme with keyCardStyle and unlockCardStyle as a parameter + // Both parameters are optional + val seamTheme = SeamTheme( + keyCard = keyCardStyle, + unlockCard = unlockCardStyle + ) + + // Set the seamTheme to SeamComponentsTheme + SeamComponentsTheme( + seamTheme = seamTheme, + colorScheme = colorScheme + ) { + SeamAccessView( + clientSessionToken = "your-token" + ) + } +} +``` +{% endcode %} +