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
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"java.configuration.updateBuildConfiguration": "automatic"
}
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.example.vonage.voicesampleapp.ui.theme

import androidx.compose.ui.graphics.Color

// Primary colors from original theme
val Purple200 = Color(0xFFBB86FC)
val Purple500 = Color(0xFF6200EE)
val Purple700 = Color(0xFF3700B3)
val Teal200 = Color(0xFF03DAC5)
val Teal700 = Color(0xFF018786)

// Custom colors from original theme
val Red = Color(0xFFC23B22)
val Green = Color(0xFF0EBE2C)
val Gray = Color(0xFF808080)
val Black = Color(0xFF000000)
val White = Color(0xFFFFFFFF)

// Material 3 color scheme colors
val Primary = Purple500
val OnPrimary = White
val PrimaryContainer = Purple700
val OnPrimaryContainer = White

val Secondary = Teal700
val OnSecondary = White
val SecondaryContainer = Teal200
val OnSecondaryContainer = Black

val Background = White
val OnBackground = Black
val Surface = White
val OnSurface = Black

val Error = Red
val OnError = White
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.example.vonage.voicesampleapp.ui.theme

import android.os.Build
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext

private val DarkColorScheme = darkColorScheme(
primary = Purple200,
onPrimary = Black,
primaryContainer = Purple700,
onPrimaryContainer = White,
secondary = Teal200,
onSecondary = Black,
secondaryContainer = Teal700,
onSecondaryContainer = White,
background = Black,
onBackground = White,
surface = Black,
onSurface = White,
error = Red,
onError = White
)

private val LightColorScheme = lightColorScheme(
primary = Primary,
onPrimary = OnPrimary,
primaryContainer = PrimaryContainer,
onPrimaryContainer = OnPrimaryContainer,
secondary = Secondary,
onSecondary = OnSecondary,
secondaryContainer = SecondaryContainer,
onSecondaryContainer = OnSecondaryContainer,
background = Background,
onBackground = OnBackground,
surface = Surface,
onSurface = OnSurface,
error = Error,
onError = OnError
)

@Composable
fun VoiceSampleAppTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
// Dynamic color is available on Android 12+
dynamicColor: Boolean = false,
content: @Composable () -> Unit
) {
val colorScheme = when {
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
val context = LocalContext.current
if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
}
darkTheme -> DarkColorScheme
else -> LightColorScheme
}

MaterialTheme(
colorScheme = colorScheme,
typography = Typography,
content = content
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.example.vonage.voicesampleapp.ui.theme

import androidx.compose.material3.Typography
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.sp

val Typography = Typography(
displayLarge = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Bold,
fontSize = 32.sp,
lineHeight = 40.sp,
letterSpacing = 0.sp
),
displayMedium = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Bold,
fontSize = 28.sp,
lineHeight = 36.sp,
letterSpacing = 0.sp
),
titleLarge = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Bold,
fontSize = 22.sp,
lineHeight = 28.sp,
letterSpacing = 0.sp
),
titleMedium = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Bold,
fontSize = 18.sp,
lineHeight = 24.sp,
letterSpacing = 0.15.sp
),
bodyLarge = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Normal,
fontSize = 16.sp,
lineHeight = 24.sp,
letterSpacing = 0.5.sp
),
bodyMedium = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Normal,
fontSize = 14.sp,
lineHeight = 20.sp,
letterSpacing = 0.25.sp
),
labelLarge = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Medium,
fontSize = 14.sp,
lineHeight = 20.sp,
letterSpacing = 0.1.sp
)
)
4 changes: 2 additions & 2 deletions contact-center/ios-voice/Podfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Uncomment the next line to define a global platform for your project
platform :ios, '13.0'
platform :ios, '15.0'
target 'VonageSDKClientVOIPExample' do
# Comment the next line if you don't want to use dynamic frameworks
use_frameworks!

# Pods for VonageSDKClientVOIPExample
pod 'VonageClientSDKVoice', '2.1.2'
pod 'VonageClientSDKVoice', '2.1.3'

end
8 changes: 4 additions & 4 deletions contact-center/ios-voice/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
PODS:
- VonageClientSDKVoice (2.1.2):
- VonageClientSDKVoice (2.1.3):
- VonageWebRTC (~> 99.14.95)
- VonageWebRTC (99.14.100)

DEPENDENCIES:
- VonageClientSDKVoice (= 2.1.2)
- VonageClientSDKVoice (= 2.1.3)

SPEC REPOS:
trunk:
- VonageClientSDKVoice
- VonageWebRTC

SPEC CHECKSUMS:
VonageClientSDKVoice: 9b5711d2209c72d6351d856343c30b4a3b10f81c
VonageClientSDKVoice: 08293daf1aa5c4f0adacbb69fa8cb83c6487e421
VonageWebRTC: c6c80961496762ac0b94aedf3ba15e91e9e22088

PODFILE CHECKSUM: 2c0fc8a7028df1ccfeff6dbb7146a183dbd05199
PODFILE CHECKSUM: 3b9d825ab6730c854b565bad8e0564fa21f86616

COCOAPODS: 1.16.2
28 changes: 28 additions & 0 deletions contact-center/ios-voice/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,34 @@

An iOS application powered by the Vonage Voice API to make and receive VOIP Calls.

## Architecture Overview

This app follows a modern SwiftUI architecture with clean separation of concerns:

### Core Components
- **`VonageVoiceApp`** - Main SwiftUI app entry point with NavigationStack-based routing
- **`CoreContext`** - Singleton managing shared services and app-wide state
- **`VoiceClientManager`** - Handles Vonage SDK integration, call lifecycle, and CallKit (device) / WebSocket (simulator)
- `+VGVoiceClientDelegate` - Extension implementing voice client delegate methods
- `+CXProviderDelegate` - Extension implementing CallKit provider delegate (device only)
- **`PushService`** - Manages VoIP and user push notifications via PushKit
- **`NetworkService`** - Generic Combine-based HTTP client for authentication APIs

### Views & ViewModels
- **`LoginView/LoginViewModel`** - Supports token-based and code-based authentication
- **`MainView`** - Home screen with username calling and floating dialer button
- **`DialerView`** - Phone number dialing and in-call DTMF input
- **`CallView`** - In-call UI with adaptive controls (incoming vs active states)

### Models
- **`VGCallWrapper`** - Observable wrapper around Vonage calls with state management
- **`CallState`** - Enum representing call lifecycle (ringing, active, holding, disconnected, reconnecting)

### Services & Utilities
- **`Configuration`** - Reads API URLs and tokens from xcconfig
- **`AppTheme`** - Centralized design system (colors, typography, spacing, button styles)
- **Extensions** - Data hex conversion, UUID utilities, Publisher helpers, Vonage SDK error conformance

## Getting Started
Note: A minimum version of Xcode 14.x is required to build and run.

Expand Down
Loading