# Hashtag Playlist Feed

Channel Hashtags Feed displays videos from a channel filtered by hashtag expressions. This allows you to create targeted content feeds based on hashtag criteria using boolean logic.

## Overview

Hashtag filter expressions use S-expression syntax to filter videos by hashtags. You can create simple or complex queries using boolean predicates (`and`, `or`) to specify what hashtags should be present on videos.

### Expression Syntax

* **Single hashtag**: `sport`
* **OR logic**: `(or sport food)` - Videos with sport OR food
* **AND logic**: `(and sport food)` - Videos with sport AND food
* **Nested logic**: `(and sport (or food comedy))` - Videos with sport AND (food OR comedy)

### Requirements

* Non-UTF-8 characters are not allowed
* Boolean predicates must be wrapped with parenthesis
* Hashtag names are case-sensitive

## Usage

### Required Parameters

* `channelId` - Your encoded channel identifier (required, non-empty)
* `hashtagFilterExpression` - Hashtag filter query (required)

### Programmatic Configuration

```kotlin
val viewOptions = viewOptions {
    baseOptions {
        feedResource(
            FeedResource.ChannelHashtag(
                channelId = "Your_Encoded_Channel_Id",
                hashtagFilterExpression = "(or food art cats pets beauty fashion travel)"
            )
        )
    }
    layoutOptions {
        feedLayout(FeedLayout.HORIZONTAL)
    }
}

val videoFeedView = findViewById<FwVideoFeedView>(R.id.videoFeedView)
videoFeedView.init(viewOptions)
```

## Filter Expression Examples

### Simple Filters

```kotlin
// Single hashtag
FeedResource.ChannelHashtag(
    channelId = "encoded_channelId",
    hashtagFilterExpression = "fashion"
)

// Multiple hashtags with OR
FeedResource.ChannelHashtag(
    channelId = "encoded_channelId",
    hashtagFilterExpression = "(or fashion style beauty)"
)
```

### Complex Filters

```kotlin
// AND logic - both hashtags required
FeedResource.ChannelHashtag(
    channelId = "encoded_channelId",
    hashtagFilterExpression = "(and fashion summer)"
)

// Nested logic
FeedResource.ChannelHashtag(
    channelId = "encoded_channelId",
    hashtagFilterExpression = "(and fashion (or summer winter spring))"
)

// Complex boolean expression
FeedResource.ChannelHashtag(
    channelId = "encoded_channelId",
    hashtagFilterExpression = "(or (and fashion summer) (and style winter))"
)
```

## Complete Example

```kotlin
class TrendingFashionActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_trending)
        
        val videoFeedView = findViewById<FwVideoFeedView>(R.id.videoFeedView)
        
        val viewOptions = viewOptions {
            baseOptions {
                feedResource(
                    FeedResource.ChannelHashtag(
                        channelId = "encoded_channelId",
                        hashtagFilterExpression = "(and fashion (or trending viral popular))"
                    )
                )
            }
            layoutOptions {
                feedLayout(FeedLayout.GRID)
                columnCount(2)
            }
            titleOptions {
                showFeedTitle(true)
            }
        }
        
        videoFeedView.init(viewOptions)
    }
}
```

## Important Notes

* **Encoded Channel ID Required** - Channel ID must be an encoded value from Firework
* **Case Sensitivity** - Hashtag names are case-sensitive
* **UTF-8 Only** - Non-UTF-8 characters are not allowed
* **Parenthesis Required** - Boolean predicates must be wrapped in parenthesis
* **Empty Expression** - Empty or invalid expressions will throw an exception
* **Channel Scope** - Only videos from the specified channel are searched

## Boolean Logic Reference

| Expression                 | Meaning                | Example                                        |
| -------------------------- | ---------------------- | ---------------------------------------------- |
| `hashtag`                  | Single hashtag         | `fashion`                                      |
| `(or a b)`                 | A OR B                 | `(or fashion beauty)`                          |
| `(and a b)`                | A AND B                | `(and fashion summer)`                         |
| `(and a (or b c))`         | A AND (B OR C)         | `(and fashion (or summer winter))`             |
| `(or (and a b) (and c d))` | (A AND B) OR (C AND D) | `(or (and fashion summer) (and style winter))` |

## See Also

* [Feed Sources Overview](https://docs.firework.com/firework-1-1/android-sdk/integration-guide/feed-sources) - All available feed types
* [Channel Feed](https://docs.firework.com/firework-1-1/android-sdk/integration-guide/feed-sources/channel-feed) - Display all videos from a channel
* [BaseOption Configuration](https://docs.firework.com/firework-1-1/android-sdk/integration-guide/configuration/base-options) - Detailed configuration
* [FwVideoFeedView](https://docs.firework.com/firework-1-1/android-sdk/integration-guide/configure-video-feed) - Video feed widget
