Skip to content

ControlKit/InboxKit-Android

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

11 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

InboxKit-Android πŸ“¬

JitPack API License Kotlin

A powerful and customizable Android library for displaying inbox-style notifications and messages using Jetpack Compose. InboxKit provides a modern, flexible solution for managing user notifications with beautiful UI components and extensive customization options.

✨ Features

  • 🎨 Modern UI: Built with Jetpack Compose for beautiful, responsive interfaces
  • πŸ”§ Highly Customizable: Extensive configuration options for colors, styles, and layouts
  • πŸ“± Multiple Styles: Support for different view styles (FullScreen, Popover)
  • πŸ”„ State Management: Robust state management with ViewModel and StateFlow
  • 🌐 Network Integration: Built-in API integration with Retrofit
  • πŸ’Ύ Local Storage: Automatic local caching with DataStore
  • πŸ›‘οΈ Error Handling: Comprehensive error handling and retry mechanisms
  • πŸ§ͺ Well Tested: Extensive unit and integration tests
  • πŸ“Š Analytics Ready: Built-in action tracking and analytics support

πŸ“Έ Screenshots

FullScreen Style

FullScreen Style

Detail Page

Detail Page

πŸš€ Installation

Step 1: Add JitPack repository

Add the JitPack repository to your project's build.gradle.kts (project level):

allprojects {
    repositories {
        google()
        mavenCentral()
        maven { url = uri("https://jitpack.io") }
    }
}

Step 2: Add dependency

Add the following to your app's build.gradle.kts:

dependencies {
    implementation("com.github.ControlKit:InboxKit-Android:0.0.1")
}

Alternative: Using version catalog

Add to your libs.versions.toml:

[versions]
inboxkit = "0.0.1"

[libraries]
inboxkit = { module = "com.github.ControlKit:InboxKit-Android", version.ref = "inboxkit" }

Then use in your build.gradle.kts:

dependencies {
    implementation(libs.inboxkit)
}

πŸ“– Quick Start

1. Basic Setup

import com.sepanta.controlkit.inboxviewkit.InboxViewKit
import com.sepanta.controlkit.inboxviewkit.inboxViewKitHost
import com.sepanta.controlkit.inboxviewkit.config.InboxViewServiceConfig
import com.sepanta.controlkit.inboxviewkit.view.config.InboxViewConfig
import com.inboxview.view.config.InboxViewStyle

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val inboxViewKit = inboxViewKitHost(
                config = InboxViewServiceConfig(
                    appId = "your-app-id",
                    version = "1.0.0",
                    viewConfig = InboxViewConfig(
                        viewStyle = InboxViewStyle.FullScreen1
                    )
                ),
                onDismiss = {
                    // Handle dismiss action
                }
            )
            
            inboxViewKit.showView()
        }
    }
}

2. Configuration

Service Configuration

val serviceConfig = InboxViewServiceConfig(
    appId = "your-unique-app-id",
    version = "1.0.0",
    deviceId = "optional-device-id", // Auto-generated if not provided
    lang = "en", // Language code
    timeOut = 5000L, // Network timeout in milliseconds
    timeRetryThreadSleep = 1000L, // Retry delay
    maxRetry = 5, // Maximum retry attempts
    viewConfig = InboxViewConfig(
        viewStyle = InboxViewStyle.FullScreen1
    )
)

View Configuration

val viewConfig = InboxViewConfig(
    viewStyle = InboxViewStyle.FullScreen1,
    
    // Header Configuration
    headerTitle = "My Inbox",
    headerTitleColor = Color.Black,
    headerTitleTextStyle = MaterialTheme.typography.headlineMedium,
    
    // Popup Configuration
    popupViewBackGroundColor = Color.White,
    popupViewCornerRadius = 16.dp,
    
    // Item Configuration
    inboxItemHeight = 96.dp,
    inboxItemTitleTextStyle = MaterialTheme.typography.bodyLarge,
    inboxItemSubjectTextStyle = MaterialTheme.typography.bodyMedium,
    inboxItemDateTextStyle = MaterialTheme.typography.bodySmall,
    
    // Search Box Configuration
    searchBoxColor = Color.Gray.copy(alpha = 0.1f),
    searchBoxCornerRadius = RoundedCornerShape(20.dp),
    
    // Button Configuration
    backButtonColor = Color.Black,
    nextButtonColor = Color.Blue,
    previousButtonColor = Color.Gray
)

🎨 Customization

Custom Views

You can provide custom views for any component:

val customConfig = InboxViewConfig(
    // Custom Header
    headerTitleView = { title ->
        Text(
            text = title,
            style = MaterialTheme.typography.headlineLarge,
            color = Color.Primary,
            modifier = Modifier.padding(16.dp)
        )
    },
    
    // Custom Inbox Item
    inboxItemView = { model, onClick ->
        Card(
            modifier = Modifier
                .fillMaxWidth()
                .clickable { onClick() }
                .padding(8.dp),
            elevation = CardDefaults.cardElevation(defaultElevation = 4.dp)
        ) {
            Column(
                modifier = Modifier.padding(16.dp)
            ) {
                Text(
                    text = model.title,
                    style = MaterialTheme.typography.titleMedium,
                    fontWeight = FontWeight.Bold
                )
                Spacer(modifier = Modifier.height(4.dp))
                Text(
                    text = model.description,
                    style = MaterialTheme.typography.bodyMedium,
                    color = Color.Gray
                )
                Spacer(modifier = Modifier.height(8.dp))
                Text(
                    text = model.date,
                    style = MaterialTheme.typography.bodySmall,
                    color = Color.Gray
                )
            }
        }
    },
    
    // Custom Back Button
    backButtonView = { onClick ->
        IconButton(onClick = onClick) {
            Icon(
                imageVector = Icons.Default.ArrowBack,
                contentDescription = "Back",
                tint = Color.Black
            )
        }
    }
)

Custom Modifiers

val configWithModifiers = InboxViewConfig(
    // Custom Layout Modifiers
    popupViewLayoutModifier = Modifier
        .fillMaxSize()
        .padding(16.dp),
    
    headerLayoutModifier = Modifier
        .fillMaxWidth()
        .padding(horizontal = 16.dp, vertical = 8.dp),
    
    inboxItemColumnLayoutModifier = Modifier
        .fillMaxWidth()
        .padding(horizontal = 16.dp),
    
    // Custom Search Box
    searchBoxLayoutModifier = Modifier
        .fillMaxWidth()
        .padding(16.dp)
        .height(48.dp),
    
    textFieldTextFieldModifier = Modifier
        .fillMaxWidth()
        .padding(horizontal = 8.dp)
)

πŸ”§ Advanced Usage

State Management

val inboxViewKit = inboxViewKitHost(
    config = serviceConfig,
    onDismiss = {
        // Handle dismiss
    },
    onState = { state ->
        when (state) {
            is InboxViewState.Initial -> {
                // Initial state
            }
            is InboxViewState.ShowData -> {
                // Data loaded successfully
            }
            is InboxViewState.NoData -> {
                // No data available
            }
            is InboxViewState.Error -> {
                // Handle error
                Log.e("InboxKit", "Error: ${state.data}")
            }
        }
    }
)

πŸ“Š Data Model

InboxViewResponse

data class InboxViewResponse(
    val id: String?,
    val version: String?,
    val title: String?,
    val description: String?,
    val iconUrl: String?,
    val linkUrl: String?,
    val sdkVersion: String?,
    val minimumVersion: String?,
    val maximumVersion: String?,
    val created_at: String?,
    val time: String?,
    val date: String?
)

API Endpoints

The library expects the following API structure:

GET /api/inbox-view

{
  "data": [
    {
      "id": "unique-id",
      "title": "Notification Title",
      "description": "Notification description",
      "date": "2024-01-15",
      "time": "14:30",
      "iconUrl": "https://example.com/icon.png",
      "linkUrl": "https://example.com/link"
    }
  ]
}

POST /api/inbox-view/{id}

{
  "appId": "your-app-id",
  "version": "1.0.0",
  "deviceId": "device-id",
  "sdkVersion": "0.0.1",
  "action": "VIEW" // or "CLICK", "DISMISS", etc.
}

🎯 View Styles

FullScreen1

  • Full-screen dialog with header and list
  • Navigation between items
  • Search functionality
  • Customizable colors and layouts

Popover1 (Coming Soon)

  • Compact popover style
  • Minimal footprint
  • Quick access to notifications

πŸ§ͺ Testing

The library includes comprehensive testing:

// Unit Tests
testImplementation("junit:junit:4.13.2")
testImplementation("io.mockk:mockk:1.14.5")
testImplementation("app.cash.turbine:turbine:1.2.1")
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.10.2")

// Integration Tests
androidTestImplementation("androidx.test.ext:junit:1.3.0")
androidTestImplementation("androidx.test.espresso:espresso-core:3.7.0")

πŸ”’ Security

  • Data encryption using Android Security Crypto
  • Secure local storage with DataStore
  • Network security with certificate pinning support
  • Input validation and sanitization

πŸ“± Requirements

  • Minimum SDK: 26 (Android 8.0)
  • Target SDK: 36 (Android 14)
  • Kotlin: 2.2.20+
  • Compose: 1.9.1+

🀝 Contributing

We welcome contributions! Please see our Contributing Guidelines for details.

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

Copyright (c) 2024 ControlKit

πŸ†˜ Support

πŸ™ Acknowledgments

  • Jetpack Compose team for the amazing UI framework
  • Square for Retrofit and OkHttp
  • Coil team for image loading
  • All contributors and users

Made with ❀️ by the ControlKit team

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •  

Languages