Skip to content

Instantly share code, notes, and snippets.

View johnkil's full-sized avatar

Evgenii Shishkin johnkil

View GitHub Profile
import java.nio.file.*
import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream
import kotlin.io.path.*
@OptIn(ExperimentalPathApi::class)
fun ZipOutputStream.addFolder(entryName: String, folder: Path) {
for (path in folder.walk()) {
val relativized = folder.relativize(path)
val prefix = if (entryName.isNotEmpty()) {
class SyncChallengesProgressUseCase @Inject constructor(
private val challengesRepository: ChallengesRepository,
private val getStepsFromFitnessApp: GetStepsFromFitnessAppUseCase,
getPhoneManufactureData: GetPhoneManufactureDataUseCase
) {
private val deviceId = getPhoneManufactureData().deviceId
suspend operator fun invoke(startDate: Instant): SyncChallengesProgressResult {
val now = Clock.System.now()
if (startDate.daysUntil(now, TimeZone.currentSystemDefault()) == 0) {
@Singleton
class OAuthTokenLocalDataSource @Inject constructor(
app: Application
) {
private val sharedPrefs: SharedPreferences = EncryptedSharedPreferences.create(
"oauth_token_local_data_source",
MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC),
app,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
import android.util.Log
import com.bugsnag.android.Bugsnag
import timber.log.Timber
import java.util.*
class BugsnagTree : Timber.DebugTree() {
// Adding one to the initial size accounts for the add before remove.
private val buffer = ArrayDeque<String>(BUFFER_SIZE + 1)
override fun isLoggable(tag: String?, priority: Int): Boolean = priority >= Log.INFO

Задача: Спроектировать Дзен как продукт

  • умная лента
  • поиск*
  • 50 мил DAU
  • текстовые статьи, фото, видео
  • каналы ,можно подписаться
  • уведомления push
  • генерация контента
@johnkil
johnkil / InitAppUpdateFlow.kt
Created April 25, 2022 15:21
Support in-app updates
private fun initAppUpdateFlow() {
logcat { "check app update" }
val appUpdateManager = AppUpdateManagerFactory.create(this)
lifecycleScope.launch {
try {
appUpdateManager.requestUpdateFlow().collect(::onAppUpdateResult)
} catch (e: InstallException) {
logcat(LogPriority.ERROR) { "Failed to request app update flow\n${e.asLog()}" }
}
}
inline class CurrencyCode private constructor(private val isoCode: String) {
override fun toString(): String = isoCode
companion object {
fun from(isoCode: String): CurrencyCode {
require(isoCode.matches("^[A-Za-z]{3}$".toRegex())) {
"Invalid ISO 4217 currency code format: $isoCode"
}
return CurrencyCode(isoCode.toUpperCase(Locale.ROOT).intern())
class CompositeOnFocusChangeListener constructor(
vararg listeners: OnFocusChangeListener
) : OnFocusChangeListener, MutableSet<OnFocusChangeListener> by listeners.toMutableSet() {
override fun onFocusChange(view: View, hasFocus: Boolean) {
forEach { it.onFocusChange(view, hasFocus) }
}
}
fun View.addOnFocusChangeListener(listener: OnFocusChangeListener) {
interface Validator<in V, out E> {
fun validate(value: V): ValidationResult<E>
}
class CompositeValidator<in V, out E>(
private vararg val validators: Validator<V, E>
) : Validator<V, E> {
override fun validate(value: V): ValidationResult<E> {
for (validator in validators) {
@johnkil
johnkil / ApiModule.java
Created November 23, 2020 20:39 — forked from koesie10/ApiModule.java
Retrofit 1 error handling behaviour in Retrofit 2
// Dagger 1 example
@Module(
complete = false,
library = true
)
public final class ApiModule {
@Provides
@Singleton
Retrofit provideRetrofit(Gson gson, Application app) {
return new Retrofit.Builder()