Skip to content

Instantly share code, notes, and snippets.

View limkhashing's full-sized avatar
:octocat:
When there is a challenge, there is an opportunity

Lim Kha Shing limkhashing

:octocat:
When there is a challenge, there is an opportunity
View GitHub Profile
@limkhashing
limkhashing / MaskPhoneNumber.kt
Created January 11, 2025 18:04
Mask phone number
fun maskPhoneNumber(input: String): String {
fun removeNonNumericalChar(input: String): String {
val result = StringBuilder()
for (char in input) {
if (char.isDigit()) {
result.append(char)
}
}
return result.toString()
}
@limkhashing
limkhashing / Cryptography.kt
Last active January 8, 2025 16:53
How to Encrypt DataStore On Android
import android.security.keystore.KeyGenParameterSpec
import android.security.keystore.KeyProperties
import java.security.KeyStore
import javax.crypto.Cipher
import javax.crypto.KeyGenerator
import javax.crypto.SecretKey
import javax.crypto.spec.IvParameterSpec
object Cryptography {
private const val KEY_ALIAS = "secret"
@limkhashing
limkhashing / my-ublock-backup_2026-01-02_18.22.01.txt
Last active January 2, 2026 10:23
uBlock Origin custom static filters
{
"timeStamp": 1767349321188,
"version": "1.68.0",
"userSettings": {
"importedLists": [],
"popupPanelSections": 63
},
"selectedFilterLists": [
"user-filters",
"ublock-filters",
@limkhashing
limkhashing / SoftInputAssist.kt
Created July 15, 2024 17:10
Android adjust layout when softkeyboard is visible
class SoftInputAssist(activity: Activity) {
private var contentContainer: ViewGroup?
private var rootView: View?
private val rootViewLayout: FrameLayout.LayoutParams?
private val contentAreaOfWindowBounds: Rect = Rect()
private var viewTreeObserver: ViewTreeObserver? = null
private var usableHeightPrevious = 0
private val listener = OnGlobalLayoutListener {
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
@limkhashing
limkhashing / AuthViewModel.kt
Last active February 14, 2026 06:59
Wrapper class for ViewModel -> View as State, returned from API
// 1. Create a State for the ViewModel, which will be observed from the Screen
data class AuthScreenState(...)
class AuthViewModel : ViewModel() {
private var _state = MutableStateFlow(AuthScreenState())
private val state = _state.stateIn(
scope = viewModelScope
started = SharingStarted.WhileSubscribed(stopTimeoutMillis = 5000)
initialValue = AuthScreenState()
)
@limkhashing
limkhashing / RVX Music_v8.30.54_rvp_v5.10.1_settings_2025-09-14.txt
Last active December 8, 2025 16:15
ReVanced Extended and Music settings
"hide_navigation_samples_button": true,
"hide_settings_menu_parent_tools": true,
"remember_playback_speed_last_selected": false,
"remember_video_quality_last_selected": false
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.rememberInfiniteTransition
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
// Producer is covariant in T
// Class body can only return T, not take T as parameter
class Producer<out T> {
fun produce() : T // ok
fun consume(item: T) // compile error
}
// Then it's possible to:
fun covariantExample(x: Producer<String>) {
val y: Producer<Any> = x // Allowed, producer is covariant in T
@limkhashing
limkhashing / BiometricPromptManager.kt
Last active March 20, 2024 17:29
Sample Biometric feature on Android
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import androidx.biometric.BiometricManager
import androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_STRONG
import androidx.biometric.BiometricManager.Authenticators.DEVICE_CREDENTIAL
import androidx.biometric.BiometricPrompt
import androidx.biometric.BiometricPrompt.PromptInfo
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.receiveAsFlow