Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
skydoves committed Oct 31, 2023
2 parents 14d3085 + 00b4ce4 commit 281a6ef
Show file tree
Hide file tree
Showing 76 changed files with 3,190 additions and 1,082 deletions.
12 changes: 6 additions & 6 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
# Common

# Core
stream-video-android @GetStream/android-developers-core
stream-video-android-pushprovider-firebase @GetStream/android-developers-core
stream-video-android @GetStream/android-developers
stream-video-android-pushprovider-firebase @GetStream/android-developers

# UI
app @GetStream/android-developers-ui
dogfooding @GetStream/android-developers-ui
stream-video-android-compose @GetStream/android-developers-ui
app @GetStream/android-developers
dogfooding @GetStream/android-developers
stream-video-android-compose @GetStream/android-developers

### Top level files and directories
# Git and GitHub
Expand Down Expand Up @@ -40,4 +40,4 @@ DokkaRoot.md @GetStream/android-developers
docusaurus @GetStream/android-developers

# Misc
.idea @GetStream/android-developers
.idea @GetStream/android-developers
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ Video roadmap and changelog is available [here](https://github.com/GetStream/pro

### 0.5.0 milestone

- [X] Development token to support a development environment
- [ ] H264 workaround on Samsung 23? (see https://github.com/livekit/client-sdk-android/blob/main/livekit-android-sdk/src/main/java/io/livekit/android/webrtc/SimulcastVideoEncoderFactoryWrapper.kt#L34 and
- https://github.com/react-native-webrtc/react-native-webrtc/issues/983#issuecomment-975624906)
- [ ] Test coverage
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ object Configuration {
const val minSdk = 24
const val majorVersion = 0
const val minorVersion = 4
const val patchVersion = 0
const val patchVersion = 1
const val versionName = "$majorVersion.$minorVersion.$patchVersion"
const val versionCode = 10
const val versionCode = 11
const val snapshotVersionName = "$majorVersion.$minorVersion.${patchVersion + 1}-SNAPSHOT"
const val artifactGroup = "io.getstream"
const val streamVideoCallGooglePlayVersion = "1.0.1"
const val streamVideoCallGooglePlayVersion = "1.0.2"
}
2 changes: 1 addition & 1 deletion docusaurus/docs/Android/02-tutorials/01-video-calling.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ If you're new to android, note that there are 2 `build.gradle` files, you want t
```kotlin
dependencies {
// Stream Video Compose SDK
implementation("io.getstream:stream-video-android-compose:0.4.0")
implementation("io.getstream:stream-video-android-compose:0.4.1")

// Optionally add Jetpack Compose if Android studio didn't automatically include them
implementation(platform("androidx.compose:compose-bom:2023.08.00"))
Expand Down
2 changes: 1 addition & 1 deletion docusaurus/docs/Android/02-tutorials/02-audio-room.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ If you're new to android, note that there are 2 `build.gradle` files, you want t
```groovy
dependencies {
// Stream Video Compose SDK
implementation("io.getstream:stream-video-android-compose:0.4.0")
implementation("io.getstream:stream-video-android-compose:0.4.1")
// Jetpack Compose (optional/ android studio typically adds them when you create a new project)
implementation(platform("androidx.compose:compose-bom:2023.08.00"))
Expand Down
2 changes: 1 addition & 1 deletion docusaurus/docs/Android/02-tutorials/03-livestream.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ If you're new to android, note that there are 2 `build.gradle` files, you want t
```kotlin
dependencies {
// Stream Video Compose SDK
implementation("io.getstream:stream-video-android-compose:0.4.0")
implementation("io.getstream:stream-video-android-compose:0.4.1")

// Jetpack Compose (optional/ android studio typically adds them when you create a new project)
implementation(platform("androidx.compose:compose-bom:2023.08.00"))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,44 +1,47 @@
# ParticipantsGrid
# ParticipantsLayout

The `ParticipantsGrid` component is one of our most versatile and complex UI components, designed to render a list of participants in a call. It handles different UI layouts based on the number of participants and different screen orientations. Additionally, it can also render screen sharing content when there is an active session.
The `ParticipantsLayout` component is one of our most versatile and complex UI components, designed to render a list of participants in a call. It handles different UI layouts based on the number of participants and different screen orientations. Additionally, it can also render screen sharing content when there is an active session.

Before jumping into how to use the component and how to customize it, let's review what some of these features mean.

What you can do with the `ParticipantsGrid` are:
What you can do with the `ParticipantsLayout` are:

- Displays a grid list of the remote/local participants.
- Supports landscape configuration.
- Renders [Screensharing](../04-call/05-screen-share-content.mdx).
- Displays a list of the remote/local participants.
- There are two available layouts, Grid and [Spotlight](04-participants-spotlight.mdx)
- There is also a dynamic option where the layout will switch automatically based on any pinned participants.
- All the layout variants are supported in portrait and in landscape mode
- Renders [Screensharing](../04-call/05-screen-share-content.mdx) on demand, regardless of selected layout.

### Flexible Layout

The `ParticipantsGrid` changes the UI layout based on the number of participants. In calls with fewer than four people, the local participant video is rendered in a floating item, using the [FloatingParticipantVideo](03-floating-participant-video.mdx). In calls with four or more people, it's rendered with other participants in a grid.
The `ParticipantsLayout` changes the UI layout based on the number of participants. In calls with fewer than four people, the local participant video is rendered in a floating item, using the [FloatingParticipantVideo](03-floating-participant-video.mdx). In calls with six or more people, it's rendered with other participants in a grid.

Additionally, the participants are rendered in the following way:

* **One participant**: Rendered as the only single item in the "grid", taking up the full component space.
* **One participant**: Rendered as the only single item in the layout, taking up the full component space.
* **Two participants** (1 remote + local): The remote participant is rendered within the full component space while the local participant is a floating item.
* **Three participants** (2 remote + local): Remote participants are in a vertical split-screen, while the local participant is a floating item.
* **Four or more participants**: (4 or more remote): Participants are rendered as a grid of items, in a paginated way. Up to 6 participants per page, with the sorted participant.
* **Three to four participants** (2-3 remote + local): Remote participants are in a vertical split-screen, while the local participant is a floating item.
* **Five or more** (4 remote + local): Participants are rendered as a grid of items, in a paginated way. Up to 6 participants per page, with the sorted participant.

Sorted participants gives you the list of participants sorted by:

* anyone who is pinned
* dominant speaker
* if you are screensharing
* last speaking at

If the participants are not visible on the screen they are also sorted by:
* is dominant speaker
* has video enabled
* has audio enabled
* all other video participants by when they joined
* audio only participants by when they joined

### Orientation

The component handles both Landscape and Portrait orientations by rendering different UI. In Portrait mode, the video layout is optimized for standard mobile device rendering, while the landscape mode offers more screen real estate to render video by adding a transparent app bar and pushing the call controls to the side. This is helpful when you need to pay attention to details of the video content of other participants.

Additionally, both of these orientations work for screen sharing and adjust the UI accordingly.

| Portrait ParticipantsGrid | Landscape ParticipantsGrid |
| Portrait ParticipantsLayout | Landscape ParticipantsLayout |
| ------- | ------------------------------------------------------------ |
| ![Portrait ParticipantsGrid](../../assets/compose_single_participant.png) | ![Landscape ParticipantsGrid](../../assets/compose_call_landscape.png) |
| ![Portrait ParticipantsLayout](../../assets/compose_single_participant.png) | ![Landscape ParticipantsLayout](../../assets/compose_call_landscape.png) |

### Screen Sharing

Expand All @@ -50,19 +53,19 @@ Users can then focus on the shared content more or choose to enter the full scre
| ------- | ------------------------------------------------------------ |
| ![Portrait Screensharing](../../assets/compose_screensharing.png) | ![Landscape Screensharing](../../assets/compose_screensharing_landscape.png) |

Now that you've learned a lot about the `ParticipantsGrid` internal works, let's see how to use the component to add it to your UI.
Now that you've learned a lot about the `ParticipantsLayout` internal works, let's see how to use the component to add it to your UI.

## Usage

To use the component in your UI, once you have the required state, you can render `CallParticipants` like so:

```kotlin
@Composable
public fun MyParticipantsGridScreen() {
public fun MyParticipantsLayoutScreen() {
Scaffold(
topBar = { /* Custom top bar */ },
) { padding ->
ParticipantsGrid(
ParticipantsLayout(
modifier = Modifier.fillMaxSize(),
call = call
)
Expand Down Expand Up @@ -107,7 +110,7 @@ In terms of UI customization, you can very easily customize each participant vid

```kotlin
@Composable
public fun ParticipantsGrid(
public fun ParticipantsLayout(
modifier: Modifier = Modifier.fillMaxSize(),
call = call,
style = RegularVideoRendererStyle(
Expand All @@ -125,7 +128,7 @@ With these options, you have more than enough space to customize how the compone
You can also custom the entire video renderer by implementing your own video renderer:

```kotlin
ParticipantsGrid(
ParticipantsLayout(
call = call,
modifier = Modifier.fillMaxSize(),
videoRenderer = { modifier, call, participant, style ->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# ParticipantsSpotlight

The `ParticipantsSpotlight` is a Composable component that allows you to highlight one participant and this one participant takes much of the screen, while the rest are rendered
either as a horizontal or vertical list depending on orientation.

Let's see how to use the `ParticipantsSpotlight`.

## Usage

To use the `ParticipantsSpotlight` component in your app you can use it direcyly as a component or you can configure the [ParticipantsLayout](02-participants-grid.mdx) to display the spotlight.

### Use it directly
```kotlin
ParticipantsSpotlight(call = call)
```
The only mandatory parameter is `call` which represents the call for which the participants are being displayed.

### Use it via [ParticipantsLayout](02-participants-grid.mdx)

If you are using the `ParticipantsLayout` you can use an enum value `LayoutType` with one of three options.

Those are:
```kotlin
//Automatically choose between Grid and Spotlight based on pinned participants and dominant speaker.
DYNAMIC

//Force a spotlight view, showing the dominant speaker or the first speaker in the list.
SPOTLIGHT

//Always show a grid layout, regardless of pinned participants.
GRID
```

Here is how it looks in action:
```kotlin
ParticipantsLayout(
layoutType = LayoutType.SPOTLIGHT,
call = call
)
```

The [ParticipantsLayout](02-participants-grid.mdx) internally displays the `ParticipantSpotlight` in two cases.
1. You have set the `layoutType` to `LayoutType.SPOTLIGHT` in which case a participant is always spotlighted. The participant shown in the spotlight is chosen based on the following order:
1. is pinned
2. is dominantSpeaker
3. is first in the participants list
2. You have set the `LayoutType` to `LayoutType.DYNAMIC` in which case if there is a "pinned" participant, the spotlight view will be chosen in favor of grid.

*Note*: `ParticipantLayout` will always prioritize screensharing regardless of the `LayoutType` if there is a [screensharing session](../04-call/05-screen-share-content.mdx).s


Using this component, you'll likely see something similar to the following UI:

![Spotlight portrait](../../assets/spotlight_portrait.png)

![Spotlight landscape](../../assets/spotlight_landscape.png)


Let's see how to customize this component.

## Customization

This is a very simple component so it doesn't have replaceable slots, but it still offers ways to customize its appearance.

- `modifier`: Modifier for styling.
- `isZoomable`: Decide if this spotlight video renderer is zoomable or not.
- `style`: Defined properties for styling a single video call track.
- `videoRenderer`: A single video renderer renders each individual participant.

If you're looking for guides on how to override and customize this UI, we have various [UI Cookbook](../../05-ui-cookbook/01-overview.mdx) recipes for you and we cover a portion of customization within the [Video Android SDK Tutorial](../../02-tutorials/01-video-calling.mdx).
2 changes: 1 addition & 1 deletion docusaurus/docs/Android/06-advanced/07-chat-with-video.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Let the project sync. It should have all the dependencies required for you to fi
```groovy
dependencies {
// Stream Video Compose SDK
implementation("io.getstream:stream-video-android-compose:0.4.0")
implementation("io.getstream:stream-video-android-compose:0.4.1")
// Stream Chat
implementation(libs.stream.chat.compose)
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions dogfooding/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,8 @@ dependencies {
implementation(libs.androidx.hilt.navigation)
implementation(libs.landscapist.coil)
implementation(libs.accompanist.permission)
implementation(libs.androidx.lifecycle.runtime.compose)
implementation(libs.coil.compose)

// hilt
implementation(libs.hilt.android)
Expand All @@ -251,6 +253,9 @@ dependencies {
implementation(libs.firebase.crashlytics)
implementation(libs.firebase.analytics)

// moshi
implementation(libs.moshi.kotlin)

// Play Install Referrer library - used to extract the meeting link from demo flow after install
implementation(libs.play.install.referrer)

Expand Down
2 changes: 1 addition & 1 deletion dogfooding/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@
</activity>

<activity
android:name="io.getstream.video.android.RingCallActivity"
android:name="io.getstream.video.android.DirectCallActivity"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
android:exported="true"
android:hardwareAccelerated="true"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ import java.util.UUID
import javax.inject.Inject

@AndroidEntryPoint
class RingCallActivity : ComponentActivity() {
class DirectCallActivity : ComponentActivity() {

@Inject
lateinit var dataStore: StreamUserDataStore
Expand Down Expand Up @@ -87,9 +87,9 @@ class RingCallActivity : ComponentActivity() {
if (result is Result.Failure) {
// Failed to recover the current state of the call
// TODO: Automaticly call this in the SDK?
Log.e("RingCallActivity", "Call.create failed ${result.value}")
Log.e("DirectCallActivity", "Call.create failed ${result.value}")
Toast.makeText(
this@RingCallActivity,
this@DirectCallActivity,
"Failed get call status (${result.value.message})",
Toast.LENGTH_SHORT,
).show()
Expand Down Expand Up @@ -163,7 +163,7 @@ class RingCallActivity : ComponentActivity() {
callId: String? = null,
members: List<String>,
): Intent {
return Intent(context, RingCallActivity::class.java).apply {
return Intent(context, DirectCallActivity::class.java).apply {
putExtra(EXTRA_CID, callId)
putExtra(EXTRA_MEMBERS_ARRAY, members.toTypedArray())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.ui.Modifier
import androidx.lifecycle.lifecycleScope
import dagger.hilt.android.AndroidEntryPoint
import io.getstream.result.Result
import io.getstream.video.android.compose.theme.VideoTheme
import io.getstream.video.android.compose.ui.components.call.activecall.CallContent
Expand All @@ -46,6 +47,7 @@ import io.getstream.video.android.util.StreamVideoInitHelper
import kotlinx.coroutines.launch
import javax.inject.Inject

@AndroidEntryPoint
class IncomingCallActivity : ComponentActivity() {

@Inject
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright (c) 2014-2023 Stream.io Inc. All rights reserved.
*
* Licensed under the Stream License;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://github.com/GetStream/stream-video-android/blob/main/LICENSE
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.getstream.video.android.data.dto

import io.getstream.video.android.models.GoogleAccount
import io.getstream.video.android.util.UserIdHelper
import java.util.Locale

data class GetGoogleAccountsResponseDto(
val people: List<GoogleAccountDto>,
)

data class GoogleAccountDto(
val photos: List<PhotoDto>?,
val emailAddresses: List<EmailAddressDto>,
)

data class PhotoDto(
val url: String,
)

data class EmailAddressDto(
val value: String,
)

fun GoogleAccountDto.asDomainModel(): GoogleAccount {
val email = emailAddresses.firstOrNull()?.value

return GoogleAccount(
email = email,
id = email?.let { UserIdHelper.getUserIdFromEmail(it) },
name = email
?.split("@")
?.firstOrNull()
?.split(".")
?.firstOrNull()
?.capitalize(Locale.ROOT) ?: email,
photoUrl = photos?.firstOrNull()?.url,
)
}
Loading

0 comments on commit 281a6ef

Please sign in to comment.