# Баннеры

Баннеры — это встраиваемые рекламные блоки внутри контента приложения c каруселями или одиночными баннерами. В каждом креативе поддерживается отображение картинок и видео.

> [!NOTE]
> Размер баннера подстраивается под ширину экрана с сохранением соотношения сторон. Высота высчитывается динамически.

![Баннеры](../../../../../../concepts/multiformat-preview.png){height="200"}

Подробнее о форматах - в разделе [Рекламные форматы](../../../../../concepts/ad-formats.md).

## 1. Загрузка рекламы

При загрузке рекламы необходимо передавать `InLineAdSlot`, который содержит `padId` (идентификатор места размещения), `position` (позиция рекламного креатива внутри места размещения).
`padId` можно получить в рекламной админке либо от менеджера.

Для отладки можно использовать тестовые `padId` (см. [Отладка](../debugging.md)).

```kotlin
import ru.tander.mads.inline.model.InLineAdRequest

val inLineAdSlot = InLineAdSlot(
    padId = "1", // идентификатор места показа рекламы
    position = 0 // позиция внутри места размещения 
)

val inLineAdRequest = InLineAdRequest(
    slot = inLineAdSlot, // уникальный slot рекламного креатива 
    targetings = emptyMap(), // параметры таргетингов
)
```

Для загрузки вызовите suspend-функцию `Mads.inLine.load(...)`:

```kotlin
import ru.tander.mads.Mads

val inLineAdResponse = Mads.InLine.load(inLineAdRequest)
```

Отмена загрузки рекламы:
```kotlin
val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())

val job = scope.launch {
    try {
        Mads.inLine.load(...)  // загрузка рекламы
    } catch (e: CancellationException) {
        println("Load cancelled")
        // Cleanup if needed
    }
}

// Cancel anytime:
job.cancel()  // Отменяет загрузку рекламы
```

### Параметры запроса

| Параметр        | Тип                   | Обязательный | Описание |
|-----------------|-----------------------|:---:|----------|
| `slot` | `InLineAdSlot` | ✅ | Идентификатор места размещения |
| `targetings`    | `Map<String, String>` | ✅ | Словарь таргетингов для персонализации рекламы |

### Параметры AdSlot

при наличии нескольких рекламных блоков на экране можно передавать один padId и разные position.
Например, в листинге товаров InLine блок может повторяться через каждые 3 ряда карточек. Необходимо для первой позиции передавать `position: 0`, для второй `position: 1` и так далее, при этом padId один и тотже.

| Параметр | Тип | Обязательный | Описание |
|----------|-----|:---:|----------|
| `padId` | `String` | ✅ | Id места размещения |
| `position` | `Int` | ❌ | Позиция внутри места размещения (по умолчанию: `0`) |

> [!TIP]
> Параллельно можно загружать несколько рекламных объявлений. Для отмены загрузки достаточно остановить работу `CoroutineScope`, в контексте которого была вызвана suspend-функция `Mads.inLine.load(...)`.

## 2. Таргетирование

Передайте словарь таргетингов при загрузке рекламы. Подробнее о таргетингах — в разделе [Таргетирование](../../../../../concepts/targeting.md).

```kotlin
val targetings: Map<String, String> = mapOf(
    "gender" to "female"
)

val inLineAdSlot = InLineAdSlot(...)

val inLineAdRequest = InLineAdRequest(
    slot = inLineAdSlot,
    targetings = emptyMap(), // параметры таргетингов
)

val inLineAdResponse = Mads.inLine.load(inLineAdRequest)
```
## 3. Обработка результата запроса и показ загруженной рекламы

Обработайте результат загрузки рекламы:

```kotlin
import ru.tander.mads.AdLoadingTimeoutException
import ru.tander.mads.inline.loading.integration_public.InLineAdResponse

when (inLineAdResponse) {
    is InLineAdResponse.Success -> {
        // show() является @Composable функцией
        inLineAdResponse.content.show(
            // отображение рекламы можно кастомизировать через передачу `Modifier`
            // при кастомизации крайне желательно учитывать разные варианты отображения рекламы
            // подробнее о вариантах отображения рекламы ниже
            modifier = when (inlineAdResponse.content.type) { ... }
        )
    }
    is InLineAdResponse.NoContent -> {
        // Запрос за рекламой завершился без ошибок, но реклама не была подобрана.
    }
    is InLineAdResponse.Failure -> {
        // Запрос за рекламой завершился с ошибой.
        if (inAppAdResponse.reason is AdLoadingTimeoutException) {
            // Превышен таймаут загрузки рекламы
        }
    }
}
```

### Возможные состояния

| Тип значения | Параметры                                   | Описание                                                                                                             |
|--------------|---------------------------------------------|----------------------------------------------------------------------------------------------------------------------|
| `Success`     | `content` - контент для отображения рекламы | Реклама загружена успешно. Отобразить загруженную рекламу можно вызвав `content.show(...)` внутри @Composable блока. |
| `Failure`    | `reason` - причина ошибки загрузки рекламы                                          | Загрузка рекламы завершилась ошибкой.                                                                                |
| `NoContent`  |  - | Запрос за рекламой завершился без ошибок, но реклама не была подобрана.                                              |

### Кастомизация отображения рекламы

`InLineAdContent#show` принимает в качестве аргумента `Modifier`, при помощи которого можно кастомизировать отображение рекламы. При кастомизации отображения рекламы крайне желательно учитывать разные варианты отображения рекламы:

```kotlin
import ru.tander.mads.inline.model.InLineAdContent

when (inlineAdResponse.content.type) {
    is InLineAdContent.Type.Empty -> {
        // пустой контент, ничего не показываем
        // inlineAdResponse.content.show() <-- в результате вызова ничего не произойдёт
    }
    is InLineAdContent.Type.Banner.Carousel -> {
        // стандартное отображение карусели баннеров нас устраивает, показываем как есть
        inlineAdResponse.content.show()
    }
    is InLineAdContent.Type.Banner.SingleItem -> {
        // при отображении одиночного баннера добавляем горизонтальные отступы
        inlineAdResponse.content.show(Modifier.padding(horizontal = 12.dp))
    }
    else -> {
        // неизвестный тип контента, показываем как есть
        inlineAdResponse.content.show()
    }
}
```

### Возможные типы контента

| Тип значения        | Описание                                                                                                                                    |
|---------------------|---------------------------------------------------------------------------------------------------------------------------------------------|
| `Empty`             | Контент для показа отсуствует. В вызове метода `show` нет необходимости.                                                                    |
| `Banner.Carousel`   | Контент в виде скроллящейся горизонтально "карусели баннеров". Для корректного отображения желательно не добавлять горизонтальных отступов. |
| `Banner.SingleItem` | Контент в виде одиночного баннера. Для корректного отображения желательно добавить горизонтальные отступы.                                  |

## 5. Реакция на действия пользователя

SDK не реагирует на действия пользвателя на рекламном объявлении (такие как "нажатие на кнопку" и т.д.). Реакцию на эти действия необходимо реализовать на стороне интегрирующего приложения:

```kotlin
import ru.tander.mads.inline.multiformat.integration_public.events.MultiformatAdActions


when (inLineAdResponse) {
    is InLineAdResponse.Success -> {
        inLineAdResponse.content.actions
            .onEach(::handleInLineAdShowingAction)
            .launchIn(...)
    }
    ...
}

fun handleInLineAdShowingAction(action: MultiformatAdActions) {
    when (action) {
        is MultiformatAdActions.OnUrlClicked -> {
            openUrl(action.type, action.url) // открытие ссылки при нажатии на кнопку на рекламном объявлении
        }
    }
}
```

### Возможные значения Banner (MultiformatAdActions)

| Тип значения                           | Параметры                                                                                                                                                        | Описание                                |
|----------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------|
| `MultiformatAdActions.OnUrlClicked`    | `adInfo` - инфомация о рекламном объявлении<br>`type` - тип ссылки (напр. "web", "deeplink" и т.д.)<br>`url` - ссылка, по которой необходимо осуществить переход | Нажатие на кнопку перехода по ссылке    |

## 6. Реакция на события показа рекламы

При необходимости приложение может отслеживать события показа рекламы, используя `InLineAdContent.events`. Описанные ниже события относятся к формату Banner; события для формата Stories — в [Stories](stories.md):

```kotlin
import ru.tander.mads.inline.multiformat.integration_public.events.MultiformatAdEvents

when (inLineAdResponse) {
    is InLineAdResponse.Success -> {
        InLineAdResponse.content.events
            .onEach(::handleInLineAdShowingEvents)
            .launchIn(...)
    }
    ...
}

fun handleInLineAdShowingEvent(event: MultiformatAdEvents) {
    when (event) {
        is MultiformatAdEvents.OnBlockView -> {
            // Рекламный блок показан
        }
        is MultiformatAdEvents.OnCreativeView -> {
            // Рекламный креатив показан
        }
    }
}
```

### Возможные значения Banner (MultiformatAdEvents)

| Тип значения                              | Параметры                                   | Описание                               |
|-------------------------------------------|---------------------------------------------|----------------------------------------|
| `MultiformatAdEvents.OnBlockView`      | `adInfo` - инфомация о рекламном объявлении | Показ рекламного блока                 |
| `MultiformatAdEvents.OnCreativeView` | `adInfo` - инфомация о рекламном объявлении | Показ рекламного креатива внутри блока |

### Информация о рекламе (MultiformatInfo)

| Поле | Тип | Описание |
|------|-----|----------|
| `slot` | `InLineAdSlot` | Информация о размещении |
| `creativeId` | `String?` | Идентификатор креатива |
| `format` | `String` | Название рекламного формата |
## Пример

Полный пример интеграции In Line рекламы — в [репозитории на GitHub](https://github.com/magnit-tech/mads-android-sdk).
