Skip to content

Instantly share code, notes, and snippets.

View mahdiPourkazemi's full-sized avatar

Mahdi Pourkazemi mahdiPourkazemi

View GitHub Profile
@mahdiPourkazemi
mahdiPourkazemi / fiveFlowUseFullPattern.kt
Created August 11, 2025 19:20
fiveFlowUseFullPattern
The One-Shot Operation as a Cold Stream
//########################################################################
class MyViewModel(private val repository: DataRepository) : ViewModel() {
private val _data = MutableStateFlow<UiState>(UiState.Loading)
val data: StateFlow<UiState> = _data
fun fetchData() {
viewModelScope.launch {
try {
_data.value = UiState.Success(repository.fetchSomeData())
@mahdiPourkazemi
mahdiPourkazemi / FunctionComposition.kt
Created August 9, 2025 14:56
Function Composition simple and with flow
@Composable
fun PriceScreen() {
val originalPrice = 150.0
val addTax = { price: Double -> price * 1.08 }
val applyDiscount = { price: Double -> price * 0.85 }
val roundPrice = { price: Double -> kotlin.math.round(price) }
val finalPrice = processPrice(originalPrice, applyDiscount, addTax, roundPrice)
@mahdiPourkazemi
mahdiPourkazemi / Coroutine.kt
Last active August 7, 2025 08:44
LaunchedEffect vs rememberCoroutineScope in compose
//########LaunchedEffect####################
// first load in page: init vs Launched Effect
@Composable
fun MyScreen(userId: String) {
LaunchedEffect(userId) {
// هر بار userId تغییر کنه اجرا میشه
val user = userRepository.getUser(userId)
println(user.name)
}
}
@mahdiPourkazemi
mahdiPourkazemi / UiStateExample.kt
Created August 4, 2025 13:50
example of handling UI state with data request
// UiState بهبود یافته با generic type
sealed class UiState<out T> {
object Loading : UiState<Nothing>()
data class Success<T>(val data: T) : UiState<T>()
data class Error(
val throwable: Throwable,
val userMessage: String,
val isRetryable: Boolean = true
) : UiState<Nothing>()
}
@mahdiPourkazemi
mahdiPourkazemi / SearchViewModel.kt
Created August 4, 2025 12:52
Search With Flow Powered
class SearchViewModel : ViewModel() {
private val _searchQuery = MutableSharedFlow<String>()
val searchResults: StateFlow<UiState<List<SearchResult>>> = _searchQuery
.debounce(300) // صبر می‌کنه تا کاربر تایپ کردن رو تموم کنه
.filter { it.length >= 3 } // حداقل 3 کاراکتر
.flatMapLatest { query ->
if (query.isEmpty()) {
flowOf(UiState.Success(emptyList()))
} else {
@Composable
fun Float.dpToPx(): Float = with(LocalDensity.current) { this@dpToPx.dp.toPx() }
@Composable
fun Int.dpToPx(): Float = with(LocalDensity.current) { this@dpToPx.dp.toPx() }
val circleRadius = 12.dp.dpToPx()
fun <T> SnapshotStateList<T>.toggle(item: T) {
if (contains(item)) remove(item) else add(item)
@mahdiPourkazemi
mahdiPourkazemi / SpanStyleText.kt
Created July 31, 2025 08:44
quoran text style with color
fun String.toAnnotatedTextWithArabicDiacritics(
diacriticsStyle: SpanStyle = SpanStyle(color = Color.Red)
): AnnotatedString {
val builder = AnnotatedString.Builder()
// اعراب عربی که باید قرمز شوند
val arabicDiacritics = setOf(
'\u064B', // فتحتان (ً)
'\u064C', // ضمتان (ٌ)
@mahdiPourkazemi
mahdiPourkazemi / constants.kt
Created July 29, 2025 11:13
This snippet demonstrates a better way to inject constant values using Hilt in Android. Instead of relying on a centralized Constants.kt file and @nAmed strings (which are error-prone and hard to refactor), it uses custom @qualifier annotations. This approach provides compile-time safety, clearer dependency injection, and easier maintenance.
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class SharedPreferencesFileNameKey
@Qualifier
@Retention(AnnotationRetention.BINARY)
annotation class LanguageCodeKey
@Module
@InstallIn(SingletonComponent::class)
@mahdiPourkazemi
mahdiPourkazemi / gist:2752ac97305a277da3928e23c47d2a04
Last active August 4, 2025 14:11
SAM applications in android
// ========== روش 1: استفاده از Interface ==========
fun interface OnItemClickListener {
fun onItemClick(item: String)
companion object {
fun withLogging(
tag: String = "ListItemClick",
messagePrefix: String = "Clicked on: ",
action: (String) -> Unit
): OnItemClickListener {
@mahdiPourkazemi
mahdiPourkazemi / NavTypeParcelableMapper.kt
Created July 21, 2025 06:55
This Kotlin extension defines a custom NavType<T> mapper for use with Jetpack Navigation when passing Parcelable objects between destinations. It also integrates Kotlinx Serialization (@serializable) for safely encoding and decoding data into string format when navigating via routes. The mapper() function simplifies handling complex objects like…
import android.os.Build
import android.os.Bundle
import android.os.Parcelable
import androidx.navigation.NavType
import kotlinx.parcelize.Parcelize
import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json