Skip to content
This repository has been archived by the owner on Jun 26, 2023. It is now read-only.

Commit

Permalink
feat: 设置项新增控制是否请求,方便调试用
Browse files Browse the repository at this point in the history
- 玩了下 DataStore
- 成功动态更新 koin 的依赖
  • Loading branch information
14720 committed Jan 5, 2022
1 parent 8231cf9 commit e861085
Show file tree
Hide file tree
Showing 6 changed files with 188 additions and 25 deletions.
5 changes: 5 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,8 @@ dependencies {

// sql
implementation("com.squareup.sqldelight:android-driver:1.5.3")

// jetpack
implementation "androidx.datastore:datastore:1.0.0"
implementation "androidx.datastore:datastore-preferences:1.0.0"
}
57 changes: 53 additions & 4 deletions app/src/main/java/com/wecom/BotFatherApp.kt
Original file line number Diff line number Diff line change
@@ -1,25 +1,74 @@
package com.wecom

import android.app.Application
import com.wecom.botfather.di.appModules
import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import com.wecom.botfather.BuildConfig
import com.wecom.botfather.di.appModule
import com.wecom.botfather.di.serviceModule
import com.wecom.botfather.mock.MockService
import com.wecom.botfather.sdk.service.WeComService
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import org.koin.android.ext.koin.androidContext
import org.koin.android.ext.koin.androidLogger
import org.koin.core.Koin
import org.koin.core.context.KoinContext
import org.koin.core.context.loadKoinModules
import org.koin.core.context.startKoin
import org.koin.core.context.unloadKoinModules
import org.koin.core.module.Module
import org.koin.dsl.module
import timber.log.Timber

typealias T = Timber

class BotFatherApp : Application() {
class BotFatherApp : Application(), CoroutineScope by MainScope() {

override fun onCreate() {
super.onCreate()
T.plant(Timber.DebugTree())
T.tag(this::class.java.simpleName)

startKoin {
allowOverride(true)
androidContext(this@BotFatherApp)
androidLogger()
modules(appModules)
modules(appModule)
}

launch {
// 监听变更
dataStore.data.collectLatest {
loadServiceModule(it[ABORT_REQUEST_KEY] ?: BuildConfig.DEBUG)
}
}
}

companion object {
private val debugModule = module { single<WeComService> { MockService() } }

/**
* Koin 允许加载同类的 module,覆盖之前的
*/
fun loadServiceModule(debug: Boolean) {
if (debug) {
loadKoinModules(debugModule)
} else {
unloadKoinModules(debugModule)
loadKoinModules(serviceModule)
}
}
}
}
}

// At the top level of your kotlin file:
val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "settings")

// abort api request
val ABORT_REQUEST_KEY = booleanPreferencesKey("abort_request")
31 changes: 13 additions & 18 deletions app/src/main/java/com/wecom/botfather/di/AppModules.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package com.wecom.botfather.di
import com.squareup.sqldelight.android.AndroidSqliteDriver
import com.squareup.sqldelight.db.SqlDriver
import com.wecom.botfather.Database
import com.wecom.botfather.mock.MockService
import com.wecom.botfather.sdk.WeComBotHelper
import com.wecom.botfather.sdk.service.WeComService
import com.wecom.botfather.ui.chat.ChatViewModel
Expand All @@ -14,27 +13,12 @@ import org.koin.dsl.module
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory

const val debug = true


val uiModules = module {
viewModel { HomeViewModel(get()) }
viewModel { ChatViewModel(get()) }
}

val sdkModules = module {
if (debug) {
// 使用日志打印代替请求
single<WeComService> { MockService() }
} else {
single<WeComService> {
Retrofit.Builder()
.baseUrl("https://qyapi.weixin.qq.com/")
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(WeComService::class.java)
}
}

single<SqlDriver> {
AndroidSqliteDriver(
Expand All @@ -48,8 +32,19 @@ val sdkModules = module {
Database(get())
}

single { WeComBotHelper(get<Database>().botQueries) }
factory { WeComBotHelper(get<Database>().botQueries) }

}

val appModules = sdkModules + uiModules
val serviceModule = module {
single<WeComService> {
Retrofit.Builder()
.baseUrl("https://qyapi.weixin.qq.com/")
.addConverterFactory(GsonConverterFactory.create())
.build()
.create(WeComService::class.java)
}
}

val appModule = uiModules + sdkModules + serviceModule

70 changes: 70 additions & 0 deletions app/src/main/java/com/wecom/botfather/ui/settings/Preferences.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package com.wecom.botfather.ui.settings

import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.material.Switch
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

@Composable
fun PreferenceWidget() {
TODO()
}

/**
* 配合 Prefrence 使用,分组展示
*/
@Composable
fun PreferenceGroup(
title: @Composable () -> Unit,
content: @Composable () -> Unit
) {
Column {
title()
content()
}
}

@Composable
fun SwitchPreference(
title: @Composable () -> Unit,
checked: Boolean,
onCheckedChange: ((Boolean) -> Unit)?,
modifier: Modifier = Modifier,
description: @Composable (() -> Unit)? = null,
) {
Row(modifier = modifier.fillMaxWidth().padding(16.dp)) {
Column(modifier = Modifier.weight(1f)) {
title()
if (description != null) {
Spacer(Modifier.size(4.dp))
description()
}
}
Spacer(Modifier.size(4.dp))
Switch(
checked = checked,
onCheckedChange = onCheckedChange,
modifier = Modifier.alignByBaseline()
)
}
}

@Preview(showBackground = true)
@Composable
fun SwitchPreferencePreview() {
SwitchPreference(
title = { Text("hahah") },
description = { Text(text = "xxxx", fontSize = 12.sp, color = Color.Gray) },
checked = true,
onCheckedChange = {},
modifier = Modifier.clickable {

}
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,24 @@ import android.content.Intent
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.clickable
import androidx.compose.material.Scaffold
import androidx.compose.material.Text
import androidx.compose.material.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.sp
import androidx.datastore.preferences.core.edit
import com.wecom.ABORT_REQUEST_KEY
import com.wecom.botfather.BuildConfig
import com.wecom.dataStore
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch

/**
* TODO
Expand All @@ -18,8 +32,18 @@ class SettingsActivity : ComponentActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val prefValue = dataStore.data.map {
it[ABORT_REQUEST_KEY] ?: BuildConfig.DEBUG
}
setContent {
SettingScreen()
val scope = rememberCoroutineScope()
SettingScreen(prefValue) { newValue ->
scope.launch {
dataStore.edit {
it[ABORT_REQUEST_KEY] = newValue
}
}
}
}
}

Expand All @@ -34,15 +58,31 @@ class SettingsActivity : ComponentActivity() {
}

@Composable
private fun SettingScreen() {
private fun SettingScreen(prefValue: Flow<Boolean>, onValueChange: (Boolean) -> Unit) {
val abortRequest by prefValue.collectAsState(false)

Scaffold(
topBar = {
TopAppBar(
title = { Text("Settings") }
)
},
content = {

SwitchPreference(
title = { Text("禁用请求") },
description = {
Text(
text = "不进行网络请求,改为 Log 输出",
fontSize = 12.sp,
color = Color.Gray
)
},
checked = abortRequest,
onCheckedChange = onValueChange,
modifier = Modifier.clickable {
onValueChange(!abortRequest)
}
)
}
)
}

0 comments on commit e861085

Please sign in to comment.