mirror of
https://github.com/easychen/pushdeer.git
synced 2024-12-05 08:29:22 +08:00
主要修改:适配微信登陆
This commit is contained in:
parent
3faff74557
commit
ad55b81b47
@ -5,14 +5,15 @@ plugins {
|
||||
}
|
||||
|
||||
android {
|
||||
|
||||
compileSdk 31
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.pushdeer.os"
|
||||
minSdk 22
|
||||
targetSdk 31
|
||||
versionCode 5
|
||||
versionName "1.0-dev-5"
|
||||
versionCode 8
|
||||
versionName "1.0-dev-8"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
vectorDrawables {
|
||||
@ -111,5 +112,7 @@ dependencies {
|
||||
|
||||
implementation 'com.github.vishalkumarsinghvi:sign-in-with-apple-button-android:0.6'
|
||||
|
||||
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.8.1'
|
||||
api 'com.tencent.mm.opensdk:wechat-sdk-android:6.8.0'
|
||||
|
||||
// debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.8.1'
|
||||
}
|
BIN
android/app/debug/PushDeer-v1.0-dev-8.apk
Normal file
BIN
android/app/debug/PushDeer-v1.0-dev-8.apk
Normal file
Binary file not shown.
20
android/app/debug/output-metadata.json
Normal file
20
android/app/debug/output-metadata.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"version": 3,
|
||||
"artifactType": {
|
||||
"type": "APK",
|
||||
"kind": "Directory"
|
||||
},
|
||||
"applicationId": "com.pushdeer.os",
|
||||
"variantName": "debug",
|
||||
"elements": [
|
||||
{
|
||||
"type": "SINGLE",
|
||||
"filters": [],
|
||||
"attributes": [],
|
||||
"versionCode": 8,
|
||||
"versionName": "1.0-dev-8",
|
||||
"outputFile": "app-debug.apk"
|
||||
}
|
||||
],
|
||||
"elementType": "File"
|
||||
}
|
16
android/app/proguard-rules.pro
vendored
16
android/app/proguard-rules.pro
vendored
@ -27,4 +27,18 @@
|
||||
# MiPush
|
||||
-keep class com.pushdeer.os.receiver.MessageReceiver {*;}
|
||||
#可以防止一个误报的 warning 导致无法成功编译,如果编译使用的 Android 版本是 23。
|
||||
-dontwarn com.xiaomi.push.**
|
||||
-dontwarn com.xiaomi.push.**
|
||||
|
||||
|
||||
# XiaoErMei
|
||||
-keep class com.tencent.mm.opensdk.** {
|
||||
*;
|
||||
}
|
||||
|
||||
-keep class com.tencent.wxop.** {
|
||||
*;
|
||||
}
|
||||
|
||||
-keep class com.tencent.mm.sdk.** {
|
||||
*;
|
||||
}
|
BIN
android/app/release/app-release.apk
Normal file
BIN
android/app/release/app-release.apk
Normal file
Binary file not shown.
20
android/app/release/output-metadata.json
Normal file
20
android/app/release/output-metadata.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"version": 3,
|
||||
"artifactType": {
|
||||
"type": "APK",
|
||||
"kind": "Directory"
|
||||
},
|
||||
"applicationId": "com.pushdeer.os",
|
||||
"variantName": "release",
|
||||
"elements": [
|
||||
{
|
||||
"type": "SINGLE",
|
||||
"filters": [],
|
||||
"attributes": [],
|
||||
"versionCode": 5,
|
||||
"versionName": "1.0-dev-5",
|
||||
"outputFile": "app-release.apk"
|
||||
}
|
||||
],
|
||||
"elementType": "File"
|
||||
}
|
@ -55,6 +55,15 @@
|
||||
android:theme="@style/Theme.PushDeer.NoActionBar"
|
||||
/>
|
||||
|
||||
<activity
|
||||
android:name=".wxapi.WXEntryActivity"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@android:style/Theme.Translucent.NoTitleBar"
|
||||
android:exported="true"
|
||||
android:taskAffinity="com.pushdeer.os"
|
||||
android:launchMode="singleTask">
|
||||
</activity>
|
||||
|
||||
<!-- miPush components start -->
|
||||
|
||||
<service
|
||||
|
@ -10,6 +10,8 @@ import com.pushdeer.os.factory.ViewModelFactory
|
||||
import com.pushdeer.os.keeper.RepositoryKeeper
|
||||
import com.pushdeer.os.keeper.StoreKeeper
|
||||
import com.pushdeer.os.values.AppKeys
|
||||
import com.tencent.mm.opensdk.openapi.IWXAPI
|
||||
import com.tencent.mm.opensdk.openapi.WXAPIFactory
|
||||
import com.xiaomi.channel.commonutils.logger.LoggerInterface
|
||||
import com.xiaomi.mipush.sdk.Logger
|
||||
import com.xiaomi.mipush.sdk.MiPushClient
|
||||
@ -21,7 +23,7 @@ class App : Application() {
|
||||
|
||||
val storeKeeper by lazy { StoreKeeper(this) }
|
||||
val database by lazy { AppDatabase.getDatabase(this) }
|
||||
val repositoryKeeper by lazy { RepositoryKeeper(database) }
|
||||
val repositoryKeeper by lazy { RepositoryKeeper(database,storeKeeper.settingStore) }
|
||||
private val pushDeerService: PushDeerApi by lazy {
|
||||
Retrofit.Builder()
|
||||
.baseUrl(PushDeerApi.baseUrl)
|
||||
@ -38,6 +40,8 @@ class App : Application() {
|
||||
)
|
||||
}
|
||||
|
||||
val iwxapi:IWXAPI by lazy { WXAPIFactory.createWXAPI(this, AppKeys.WX_Id, true) }
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
//初始化push推送服务
|
||||
@ -52,10 +56,27 @@ class App : Application() {
|
||||
|
||||
override fun log(content: String, t: Throwable) {
|
||||
Log.d(TAG, content, t)
|
||||
Thread{
|
||||
repositoryKeeper.logDogRepository.log(
|
||||
entity = "mipush",
|
||||
level = "e",
|
||||
event = t.message.toString(),
|
||||
log = content
|
||||
)
|
||||
}.start()
|
||||
}
|
||||
|
||||
override fun log(content: String) {
|
||||
Log.d(TAG, content)
|
||||
// Thread{
|
||||
// repositoryKeeper.logDogRepository.log(
|
||||
// entity = "mipush",
|
||||
// level = "d",
|
||||
// event = "",
|
||||
// log = content
|
||||
// )
|
||||
// }.start()
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -1,10 +1,9 @@
|
||||
package com.pushdeer.os
|
||||
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.*
|
||||
import android.os.Bundle
|
||||
import android.text.util.Linkify
|
||||
import android.util.Log
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.viewModels
|
||||
@ -17,7 +16,7 @@ import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
@ -36,10 +35,13 @@ import com.pushdeer.os.ui.theme.PushDeerTheme
|
||||
import com.pushdeer.os.util.ActivityOpener
|
||||
import com.pushdeer.os.util.NotificationUtil
|
||||
import com.pushdeer.os.util.SystemUtil
|
||||
import com.pushdeer.os.values.AppKeys
|
||||
import com.pushdeer.os.viewmodel.LogDogViewModel
|
||||
import com.pushdeer.os.viewmodel.MessageViewModel
|
||||
import com.pushdeer.os.viewmodel.PushDeerViewModel
|
||||
import com.pushdeer.os.viewmodel.UiViewModel
|
||||
import com.pushdeer.os.wxapi.WXEntryActivity
|
||||
import com.tencent.mm.opensdk.constants.ConstantsAPI
|
||||
import io.noties.markwon.Markwon
|
||||
import io.noties.markwon.image.coil.CoilImagesPlugin
|
||||
import io.noties.markwon.linkify.LinkifyPlugin
|
||||
@ -58,7 +60,6 @@ class MainActivity : AppCompatActivity(), RequestHolder {
|
||||
override val logDogViewModel: LogDogViewModel by viewModels { viewModelFactory }
|
||||
override val messageViewModel: MessageViewModel by viewModels { viewModelFactory }
|
||||
override val settingStore: SettingStore by lazy { (application as App).storeKeeper.settingStore }
|
||||
override val fragmentManager: FragmentManager by lazy { this.supportFragmentManager }
|
||||
|
||||
override val coilImageLoader: ImageLoader by lazy {
|
||||
ImageLoader.Builder(this)
|
||||
@ -89,6 +90,13 @@ class MainActivity : AppCompatActivity(), RequestHolder {
|
||||
) as ClipboardManager
|
||||
) {}
|
||||
}
|
||||
override val weChatLogin: RequestHolder.WeChatLoginRequest by lazy {
|
||||
object : RequestHolder.WeChatLoginRequest((application as App).iwxapi) {}
|
||||
}
|
||||
|
||||
override val appleLogin: RequestHolder.AppleLoginRequest by lazy {
|
||||
object : RequestHolder.AppleLoginRequest(supportFragmentManager, this) {}
|
||||
}
|
||||
|
||||
override val markdown: Markwon by lazy {
|
||||
Markwon.builder(this)
|
||||
@ -103,11 +111,64 @@ class MainActivity : AppCompatActivity(), RequestHolder {
|
||||
override lateinit var qrScanActivityOpener: ActivityResultLauncher<Intent>
|
||||
override lateinit var requestPermissionOpener: ActivityResultLauncher<Array<String>>
|
||||
|
||||
val wxRegReceiver: BroadcastReceiver by lazy {
|
||||
object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
intent?.let {
|
||||
when (it.action) {
|
||||
ConstantsAPI.ACTION_REFRESH_WXAPP -> {
|
||||
weChatLogin.iwxapi.registerApp(AppKeys.WX_Id)
|
||||
}
|
||||
WXEntryActivity.ACTION_RETURN_CODE -> {
|
||||
val code = intent.getStringExtra(WXEntryActivity.CODE_KEY)!!
|
||||
lifecycleScope.launch {
|
||||
if (pushDeerViewModel.userInfo.isAppleLogin) {
|
||||
Log.d("WH_", "onReceive: isAppleLogin")
|
||||
// if login, perform merge
|
||||
coroutineScope.launch {
|
||||
pushDeerViewModel.userMerge(
|
||||
"wechat",
|
||||
code
|
||||
) {
|
||||
coroutineScope.launch {
|
||||
pushDeerViewModel.userInfo()
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Log.d("WH_", "onReceive: plainLogin")
|
||||
// if not, plain login
|
||||
coroutineScope.launch {
|
||||
pushDeerViewModel.loginWithWeiXin(code) {
|
||||
globalNavController.navigate("main") {
|
||||
globalNavController.popBackStack()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ExperimentalAnimationApi
|
||||
@ExperimentalMaterialApi
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
registerReceiver(wxRegReceiver,
|
||||
IntentFilter().apply {
|
||||
addAction(ConstantsAPI.ACTION_REFRESH_WXAPP)
|
||||
addAction(WXEntryActivity.ACTION_RETURN_CODE)
|
||||
})
|
||||
|
||||
|
||||
NotificationUtil.setupChannel(this)
|
||||
|
||||
myActivity = this
|
||||
@ -124,7 +185,7 @@ class MainActivity : AppCompatActivity(), RequestHolder {
|
||||
Color.Transparent,
|
||||
useDarkIcons
|
||||
)
|
||||
else -> systemUiController.setSystemBarsColor(Color.Transparent, useDarkIcons)
|
||||
else -> systemUiController.setSystemBarsColor(Color.Transparent, !useDarkIcons)
|
||||
}
|
||||
WindowCompat.setDecorFitsSystemWindows(window, true)
|
||||
miPushRepository.regId.observe(this) {
|
||||
@ -133,7 +194,7 @@ class MainActivity : AppCompatActivity(), RequestHolder {
|
||||
|
||||
SideEffect {
|
||||
coroutineScope.launch {
|
||||
pushDeerViewModel.login(onReturn = {
|
||||
pushDeerViewModel.loginWithApple(onReturn = {
|
||||
globalNavController.navigate("main") {
|
||||
globalNavController.popBackStack()
|
||||
}
|
||||
@ -165,4 +226,9 @@ class MainActivity : AppCompatActivity(), RequestHolder {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
unregisterReceiver(wxRegReceiver)
|
||||
}
|
||||
}
|
@ -13,7 +13,19 @@ interface PushDeerApi {
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST("/login/idtoken")
|
||||
suspend fun loginIdToken(@Field("idToken") idToken: String): ReturnData<TokenOnly>
|
||||
suspend fun loginWithAppleIdToken(@Field("idToken") idToken: String): ReturnData<TokenOnly>
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST("/login/wecode")
|
||||
suspend fun loginWithWeXin(@Field("code") code: String): ReturnData<TokenOnly>
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST("/user/merge")
|
||||
suspend fun userMerge(
|
||||
@Field("token") token: String,
|
||||
@Field("type") type: String, // apple wechat
|
||||
@Field("tokenorcode") tokenorcode: String // input idToken / code
|
||||
): String
|
||||
|
||||
// @GET("/login/fake")
|
||||
// suspend fun fakeLogin(): ReturnData<TokenOnly>
|
||||
|
@ -2,22 +2,44 @@ package com.pushdeer.os.data.api.data.response
|
||||
|
||||
class UserInfo {
|
||||
var id: String = ""
|
||||
// var uid: String = ""
|
||||
var name: String = ""
|
||||
var email: String = ""
|
||||
var app_id: String = ""
|
||||
var wechat_id: String = ""
|
||||
var apple_id: String? = ""
|
||||
var wechat_id: String? = ""
|
||||
var level: Int = 1
|
||||
var created_at: String = ""
|
||||
var updated_at: String = ""
|
||||
|
||||
override fun toString(): String {
|
||||
return "id:$id\n" +
|
||||
// "uid:$uid\n" +
|
||||
"name:$name\n" +
|
||||
"email:$email\n" +
|
||||
"app_id:$app_id\n" +
|
||||
"apple_id:$apple_id\n" +
|
||||
"wechat_id:$wechat_id\n" +
|
||||
"level:$level\n" +
|
||||
"created:$created_at\n" +
|
||||
"updated:$updated_at"
|
||||
}
|
||||
|
||||
val isWeChatLogin: Boolean
|
||||
get() {
|
||||
return if (wechat_id == null) {
|
||||
false
|
||||
} else {
|
||||
wechat_id!!.length > 4
|
||||
}
|
||||
}
|
||||
val isAppleLogin: Boolean
|
||||
get() {
|
||||
return if (apple_id == null) {
|
||||
false
|
||||
} else {
|
||||
apple_id!!.length > 4
|
||||
}
|
||||
}
|
||||
|
||||
val isLogin: Boolean
|
||||
get() = isWeChatLogin or isAppleLogin
|
||||
}
|
@ -15,6 +15,9 @@ interface LogDogDao {
|
||||
@Insert
|
||||
suspend fun insert(vararg logDog: LogDog)
|
||||
|
||||
@Insert
|
||||
fun insert1(vararg logDog: LogDog)
|
||||
|
||||
@Query("delete from LogDog")
|
||||
suspend fun clear()
|
||||
}
|
@ -18,6 +18,7 @@ class LogDog {
|
||||
return "id:$id\n" +
|
||||
"level:$level\n" +
|
||||
"entity:$entity\n" +
|
||||
"event:$event\n" +
|
||||
"log:$log\n" +
|
||||
"time:${timestamp.toTimestamp()}"
|
||||
}
|
||||
|
@ -2,13 +2,14 @@ package com.pushdeer.os.data.repository
|
||||
|
||||
import com.pushdeer.os.data.database.dao.LogDogDao
|
||||
import com.pushdeer.os.data.database.entity.LogDog
|
||||
import com.pushdeer.os.store.SettingStore
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class LogDogRepository(private val logDogDao: LogDogDao) {
|
||||
class LogDogRepository(private val logDogDao: LogDogDao,private val settingStore: SettingStore) {
|
||||
val all = logDogDao.all
|
||||
|
||||
suspend fun clear(){
|
||||
suspend fun clear() {
|
||||
logDogDao.clear()
|
||||
}
|
||||
|
||||
@ -28,6 +29,20 @@ class LogDogRepository(private val logDogDao: LogDogDao) {
|
||||
}
|
||||
}
|
||||
|
||||
fun log(
|
||||
entity: String,
|
||||
level: String,
|
||||
event: String,
|
||||
log: String
|
||||
) {
|
||||
logDogDao.insert1(LogDog().apply {
|
||||
this.entity = entity
|
||||
this.level = level
|
||||
this.event = event
|
||||
this.log = log
|
||||
})
|
||||
}
|
||||
|
||||
suspend fun logi(entity: String, event: String, log: String) {
|
||||
withContext(Dispatchers.IO) {
|
||||
insert(LogDog.logi(entity, event, log))
|
||||
|
@ -4,6 +4,7 @@ import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Intent
|
||||
import android.content.res.Resources
|
||||
import android.util.Log
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
@ -23,7 +24,12 @@ import com.pushdeer.os.viewmodel.LogDogViewModel
|
||||
import com.pushdeer.os.viewmodel.MessageViewModel
|
||||
import com.pushdeer.os.viewmodel.PushDeerViewModel
|
||||
import com.pushdeer.os.viewmodel.UiViewModel
|
||||
import com.tencent.mm.opensdk.modelmsg.SendAuth
|
||||
import com.tencent.mm.opensdk.openapi.IWXAPI
|
||||
import com.wh.common.activity.QrScanActivity
|
||||
import com.willowtreeapps.signinwithapplebutton.SignInWithAppleConfiguration
|
||||
import com.willowtreeapps.signinwithapplebutton.SignInWithAppleResult
|
||||
import com.willowtreeapps.signinwithapplebutton.SignInWithAppleService
|
||||
import io.noties.markwon.Markwon
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.delay
|
||||
@ -40,16 +46,20 @@ interface RequestHolder {
|
||||
val myActivity: AppCompatActivity
|
||||
val markdown: Markwon
|
||||
val qrScanActivityOpener: ActivityResultLauncher<Intent>
|
||||
val requestPermissionOpener:ActivityResultLauncher<Array<String>>
|
||||
val requestPermissionOpener: ActivityResultLauncher<Array<String>>
|
||||
val coilImageLoader: ImageLoader
|
||||
|
||||
val fragmentManager: FragmentManager
|
||||
|
||||
// requests
|
||||
val alert: AlertRequest
|
||||
val key:KeyRequest
|
||||
val device:DeviceRequest
|
||||
val message:MessageRequest
|
||||
val clip:ClipRequest
|
||||
val key: KeyRequest
|
||||
val device: DeviceRequest
|
||||
val message: MessageRequest
|
||||
val clip: ClipRequest
|
||||
val weChatLogin: WeChatLoginRequest
|
||||
val appleLogin: AppleLoginRequest
|
||||
|
||||
// val iwxapi: IWXAPI
|
||||
|
||||
fun startQrScanActivity() {
|
||||
qrScanActivityOpener.launch(QrScanActivity.forScanResultIntent(myActivity))
|
||||
@ -61,29 +71,98 @@ interface RequestHolder {
|
||||
}
|
||||
|
||||
fun clearLogDog() {
|
||||
alert.alert(R.string.global_alert_title_confirm,"Clear?",onOk = {
|
||||
logDogViewModel.clear()
|
||||
alert.alert(R.string.global_alert_title_confirm, "Clear?", onOk = {
|
||||
logDogViewModel.clear()
|
||||
})
|
||||
}
|
||||
|
||||
fun userRename(newName:String){
|
||||
abstract class AppleLoginRequest(
|
||||
private val fragmentManager: FragmentManager,
|
||||
private val requestHolder: RequestHolder
|
||||
) {
|
||||
private val appleLoginCallBack: (SignInWithAppleResult) -> Unit =
|
||||
{ result: SignInWithAppleResult ->
|
||||
when (result) {
|
||||
is SignInWithAppleResult.Success -> {
|
||||
if (requestHolder.pushDeerViewModel.userInfo.isWeChatLogin) {
|
||||
// if login with wechat, perform merge
|
||||
requestHolder.coroutineScope.launch {
|
||||
requestHolder.pushDeerViewModel.userMerge(
|
||||
type = "apple",
|
||||
tokenorcode = result.idToken,
|
||||
onReturn = {
|
||||
requestHolder.coroutineScope.launch {
|
||||
requestHolder.pushDeerViewModel.userInfo()
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
} else {
|
||||
// else ( is not login ), plain login with apple
|
||||
requestHolder.coroutineScope.launch {
|
||||
requestHolder.pushDeerViewModel.loginWithApple(result.idToken) {
|
||||
requestHolder.globalNavController.navigate("main") {
|
||||
requestHolder.globalNavController.popBackStack()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is SignInWithAppleResult.Failure -> {
|
||||
requestHolder.alert.alert("Warning Apple Id Login Failed", {
|
||||
result.error.message
|
||||
}, onOk = {})
|
||||
Log.d(
|
||||
"WH_",
|
||||
"Received error from Apple Sign In ${result.error.message}"
|
||||
)
|
||||
}
|
||||
is SignInWithAppleResult.Cancel -> {
|
||||
Log.d("WH_", "User canceled Apple Sign In")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val appleLoginConfiguration = SignInWithAppleConfiguration.Builder()
|
||||
.clientId("com.pushdeer.site")
|
||||
.redirectUri("https://api2.pushdeer.com/callback/apple")
|
||||
.responseType(SignInWithAppleConfiguration.ResponseType.ALL)
|
||||
.scope(SignInWithAppleConfiguration.Scope.EMAIL)
|
||||
.build()
|
||||
|
||||
val login = {
|
||||
val service = SignInWithAppleService(
|
||||
fragmentManager = fragmentManager,
|
||||
fragmentTag = "SignInWithAppleButton-1-SignInWebViewDialogFragment",
|
||||
configuration = appleLoginConfiguration,
|
||||
callback = appleLoginCallBack
|
||||
)
|
||||
service.show()
|
||||
}
|
||||
}
|
||||
|
||||
// abstract class LogDogRequest(private val )
|
||||
abstract class WeChatLoginRequest(val iwxapi: IWXAPI) {
|
||||
val login: () -> Unit = {
|
||||
val req = SendAuth.Req()
|
||||
req.scope = "snsapi_userinfo"
|
||||
req.state = System.currentTimeMillis().toString()
|
||||
iwxapi.sendReq(req)
|
||||
}
|
||||
}
|
||||
|
||||
abstract class ClipRequest(private val clipboardManager: ClipboardManager) {
|
||||
fun copyMessagePlainText(str: String) {
|
||||
clipboardManager.setPrimaryClip(ClipData.newPlainText("pushdeer-copy-plain-text", str))
|
||||
}
|
||||
|
||||
fun copyPushKey(str: String){
|
||||
fun copyPushKey(str: String) {
|
||||
clipboardManager.setPrimaryClip(ClipData.newPlainText("pushdeer-copy-pushkey", str))
|
||||
}
|
||||
}
|
||||
|
||||
abstract class AlertRequest(private val resources: Resources) {
|
||||
val show: MutableState<Boolean> = mutableStateOf(false)
|
||||
val show2BtnDialog: MutableState<Boolean> = mutableStateOf(false)
|
||||
val show1BtnDialog: MutableState<Boolean> = mutableStateOf(false)
|
||||
var title: String = ""
|
||||
var content: @Composable () -> Unit = {}
|
||||
var onOKAction: () -> Unit = {}
|
||||
@ -94,19 +173,34 @@ interface RequestHolder {
|
||||
title: String,
|
||||
content: @Composable () -> Unit,
|
||||
onOk: () -> Unit,
|
||||
onCancel: () -> Unit = {}
|
||||
) {
|
||||
this.title = title
|
||||
this.content = content
|
||||
this.onOKAction = onOk
|
||||
this.show1BtnDialog.value = true
|
||||
}
|
||||
|
||||
fun alert(
|
||||
title: String,
|
||||
content: @Composable () -> Unit,
|
||||
onOk: () -> Unit,
|
||||
onCancel: () -> Unit
|
||||
) {
|
||||
this.title = title
|
||||
this.content = content
|
||||
this.onOKAction = onOk
|
||||
this.onCancelAction = onCancel
|
||||
this.show.value = true
|
||||
this.show2BtnDialog.value = true
|
||||
}
|
||||
|
||||
fun alert(title: String, content: String, onOk: () -> Unit, onCancel: () -> Unit = {}) {
|
||||
alert(title, { Text(text = content) }, onOk, onCancel)
|
||||
}
|
||||
|
||||
fun alert(title: String, content: String, onOk: () -> Unit) {
|
||||
alert(title, { Text(text = content) }, onOk)
|
||||
}
|
||||
|
||||
fun alert(
|
||||
@StringRes title: Int,
|
||||
@StringRes content: Int,
|
||||
@ -116,6 +210,14 @@ interface RequestHolder {
|
||||
alert(resources.getString(title), resources.getString(content), onOk, onCancel)
|
||||
}
|
||||
|
||||
fun alert(
|
||||
@StringRes title: Int,
|
||||
@StringRes content: Int,
|
||||
onOk: () -> Unit = {},
|
||||
) {
|
||||
alert(resources.getString(title), resources.getString(content), onOk)
|
||||
}
|
||||
|
||||
fun alert(
|
||||
@StringRes title: Int,
|
||||
content: @Composable () -> Unit,
|
||||
@ -125,6 +227,14 @@ interface RequestHolder {
|
||||
alert(resources.getString(title), content, onOk, onCancel)
|
||||
}
|
||||
|
||||
fun alert(
|
||||
@StringRes title: Int,
|
||||
content: @Composable () -> Unit,
|
||||
onOk: () -> Unit,
|
||||
) {
|
||||
alert(resources.getString(title), content, onOk)
|
||||
}
|
||||
|
||||
fun alert(
|
||||
@StringRes title: Int,
|
||||
content: String,
|
||||
@ -133,9 +243,17 @@ interface RequestHolder {
|
||||
) {
|
||||
alert(resources.getString(title), content, onOk, onCancel)
|
||||
}
|
||||
|
||||
fun alert(
|
||||
@StringRes title: Int,
|
||||
content: String,
|
||||
onOk: () -> Unit,
|
||||
) {
|
||||
alert(resources.getString(title), content, onOk)
|
||||
}
|
||||
}
|
||||
|
||||
abstract class KeyRequest(private val requestHolder: RequestHolder){
|
||||
abstract class KeyRequest(private val requestHolder: RequestHolder) {
|
||||
fun gen() {
|
||||
requestHolder.coroutineScope.launch {
|
||||
requestHolder.pushDeerViewModel.keyGen()
|
||||
@ -166,7 +284,7 @@ interface RequestHolder {
|
||||
}
|
||||
}
|
||||
|
||||
abstract class DeviceRequest(private val requestHolder: RequestHolder){
|
||||
abstract class DeviceRequest(private val requestHolder: RequestHolder) {
|
||||
fun deviceReg(deviceInfo: DeviceInfo) {
|
||||
requestHolder.coroutineScope.launch {
|
||||
requestHolder.pushDeerViewModel.deviceReg(deviceInfo)
|
||||
@ -191,7 +309,7 @@ interface RequestHolder {
|
||||
}
|
||||
}
|
||||
|
||||
abstract class MessageRequest(private val requestHolder: RequestHolder){
|
||||
abstract class MessageRequest(private val requestHolder: RequestHolder) {
|
||||
fun messagePush(text: String, desp: String, type: String, pushkey: String) {
|
||||
requestHolder.coroutineScope.launch {
|
||||
requestHolder.pushDeerViewModel.messagePush(text, desp, type, pushkey)
|
||||
@ -200,16 +318,21 @@ interface RequestHolder {
|
||||
|
||||
fun messagePushTest(text: String) {
|
||||
if (requestHolder.pushDeerViewModel.keyList.isNotEmpty()) {
|
||||
messagePush(text, "pushtest", "markdown", requestHolder.pushDeerViewModel.keyList[0].key)
|
||||
messagePush(
|
||||
text,
|
||||
"pushtest",
|
||||
"markdown",
|
||||
requestHolder.pushDeerViewModel.keyList[0].key
|
||||
)
|
||||
requestHolder.coroutineScope.launch {
|
||||
delay(1000)
|
||||
delay(900)
|
||||
requestHolder.pushDeerViewModel.messageList()
|
||||
}
|
||||
} else {
|
||||
requestHolder.alert.alert(
|
||||
R.string.global_alert_title_alert,
|
||||
R.string.main_message_send_alert,
|
||||
onOk = {})
|
||||
R.string.main_message_send_alert
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,9 +4,10 @@ import com.pushdeer.os.data.database.AppDatabase
|
||||
import com.pushdeer.os.data.repository.LogDogRepository
|
||||
import com.pushdeer.os.data.repository.MessageRepository
|
||||
import com.pushdeer.os.data.repository.MiPushRepository
|
||||
import com.pushdeer.os.store.SettingStore
|
||||
|
||||
class RepositoryKeeper(database: AppDatabase) {
|
||||
class RepositoryKeeper(database: AppDatabase,settingStore: SettingStore) {
|
||||
val miPushRepository = MiPushRepository()
|
||||
val logDogRepository = LogDogRepository(database.logDogDao())
|
||||
val logDogRepository = LogDogRepository(database.logDogDao(),settingStore)
|
||||
val messageRepository = MessageRepository(database.messageDao())
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package com.pushdeer.os.okhttp
|
||||
|
||||
import android.util.Log
|
||||
import com.pushdeer.os.data.repository.LogDogRepository
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.Response
|
||||
|
||||
class LogInterceptor(private val logDogRepository: LogDogRepository): Interceptor{
|
||||
override fun intercept(chain: Interceptor.Chain): Response {
|
||||
val request = chain.request()
|
||||
|
||||
val url = request.url
|
||||
val methods = request.method
|
||||
val isHttps = request.isHttps
|
||||
val contentType = request.body?.contentType()
|
||||
|
||||
val response = chain.proceed(request)
|
||||
|
||||
Log.d("WH_", "intercept: $response.")
|
||||
|
||||
return response
|
||||
}
|
||||
}
|
@ -18,4 +18,6 @@ class SettingStore(context:Context) {
|
||||
var showMessageSender by store.boolean("show-message-sender",true)
|
||||
var thisPushSdk by store.string("this-push-sdk","mi-push")
|
||||
var thisDeviceId by store.string("this-device-id","")
|
||||
|
||||
var logLevel by store.string("log-level","i") // i w e - d
|
||||
}
|
@ -30,12 +30,12 @@ fun CardItemSingleLineWithIcon(
|
||||
) {
|
||||
Card(
|
||||
onClick = onClick,
|
||||
shape = RoundedCornerShape(4.dp),
|
||||
shape = RoundedCornerShape(8.dp),
|
||||
modifier = Modifier
|
||||
.border(
|
||||
width = 1.dp,
|
||||
color = MainBlue,
|
||||
shape = RoundedCornerShape(4.dp)
|
||||
shape = RoundedCornerShape(8.dp)
|
||||
),
|
||||
elevation = 5.dp
|
||||
|
||||
@ -72,13 +72,13 @@ fun CardItemMultiLine(
|
||||
) {
|
||||
Card(
|
||||
onClick = onClick,
|
||||
shape = RoundedCornerShape(4.dp),
|
||||
shape = RoundedCornerShape(8.dp),
|
||||
modifier = Modifier
|
||||
// .padding(bottom = 16.dp)
|
||||
.border(
|
||||
width = 1.dp,
|
||||
color = MainBlue,
|
||||
shape = RoundedCornerShape(4.dp)
|
||||
shape = RoundedCornerShape(8.dp)
|
||||
),
|
||||
elevation = 5.dp
|
||||
|
||||
@ -111,12 +111,12 @@ fun CardItemMultiLine(
|
||||
fun CardItemWithContent(onClick: () -> Unit, content: @Composable () -> Unit = {}) {
|
||||
Card(
|
||||
onClick = onClick,
|
||||
shape = RoundedCornerShape(4.dp),
|
||||
shape = RoundedCornerShape(8.dp),
|
||||
modifier = Modifier
|
||||
.border(
|
||||
width = 1.dp,
|
||||
color = MainBlue,
|
||||
shape = RoundedCornerShape(4.dp)
|
||||
shape = RoundedCornerShape(8.dp)
|
||||
),
|
||||
content = content,
|
||||
elevation = 5.dp
|
||||
@ -127,12 +127,12 @@ fun CardItemWithContent(onClick: () -> Unit, content: @Composable () -> Unit = {
|
||||
@Composable
|
||||
fun CardItemWithContent(content: @Composable () -> Unit = {}) {
|
||||
Card(
|
||||
shape = RoundedCornerShape(4.dp),
|
||||
shape = RoundedCornerShape(8.dp),
|
||||
modifier = Modifier
|
||||
.border(
|
||||
width = 1.dp,
|
||||
color = MainBlue,
|
||||
shape = RoundedCornerShape(4.dp)
|
||||
shape = RoundedCornerShape(8.dp)
|
||||
),
|
||||
content = content,
|
||||
elevation = 5.dp
|
||||
|
@ -176,7 +176,7 @@ fun KeyItem(key: PushKey, requestHolder: RequestHolder) {
|
||||
backgroundColor = MaterialTheme.colors.MBlue,
|
||||
contentColor = Color.White
|
||||
),
|
||||
shape = RoundedCornerShape(6.dp)
|
||||
shape = RoundedCornerShape(8.dp)
|
||||
) {
|
||||
Text(text = stringResource(id = R.string.main_key_copy))
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ fun PlainTextMessageItem(message: MessageEntity,requestHolder: RequestHolder) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(4.dp))
|
||||
.clip(RoundedCornerShape(8.dp))
|
||||
.clickable {
|
||||
requestHolder.clip.copyMessagePlainText(message.text)
|
||||
}
|
||||
@ -80,7 +80,7 @@ fun ImageMessageItem(message: MessageEntity, requestHolder: RequestHolder) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(4.dp))
|
||||
.clip(RoundedCornerShape(8.dp))
|
||||
.clickable {
|
||||
requestHolder.clip.copyMessagePlainText(message.text)
|
||||
}
|
||||
@ -125,7 +125,7 @@ fun MarkdownMessageItem(message: MessageEntity, requestHolder: RequestHolder) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(4.dp))
|
||||
.clip(RoundedCornerShape(8.dp))
|
||||
.clickable {
|
||||
requestHolder.clip.copyMessagePlainText(message.text)
|
||||
}
|
||||
|
@ -10,13 +10,13 @@ import com.pushdeer.os.holder.RequestHolder
|
||||
|
||||
@Composable
|
||||
fun MyAlertDialog(alertRequest: RequestHolder.AlertRequest) {
|
||||
if (alertRequest.show.value) {
|
||||
if (alertRequest.show2BtnDialog.value) {
|
||||
AlertDialog(
|
||||
onDismissRequest = { alertRequest.show.value = false },
|
||||
onDismissRequest = { alertRequest.show2BtnDialog.value = false },
|
||||
confirmButton = {
|
||||
TextButton(onClick = {
|
||||
alertRequest.onOKAction.invoke()
|
||||
alertRequest.show.value = false
|
||||
alertRequest.show2BtnDialog.value = false
|
||||
}) {
|
||||
Text(text = stringResource(id = R.string.global_alert_ok))
|
||||
}
|
||||
@ -25,7 +25,7 @@ fun MyAlertDialog(alertRequest: RequestHolder.AlertRequest) {
|
||||
dismissButton = {
|
||||
TextButton(onClick = {
|
||||
alertRequest.onCancelAction.invoke()
|
||||
alertRequest.show.value = false
|
||||
alertRequest.show2BtnDialog.value = false
|
||||
}) {
|
||||
Text(text = stringResource(id = R.string.global_alert_cancel))
|
||||
}
|
||||
@ -35,4 +35,20 @@ fun MyAlertDialog(alertRequest: RequestHolder.AlertRequest) {
|
||||
text = alertRequest.content
|
||||
)
|
||||
}
|
||||
if (alertRequest.show1BtnDialog.value){
|
||||
AlertDialog(
|
||||
onDismissRequest = { alertRequest.show1BtnDialog.value = false },
|
||||
confirmButton = {
|
||||
TextButton(onClick = {
|
||||
alertRequest.onOKAction.invoke()
|
||||
alertRequest.show1BtnDialog.value = false
|
||||
}) {
|
||||
Text(text = stringResource(id = R.string.global_alert_ok))
|
||||
}
|
||||
|
||||
},
|
||||
title = { Text(text = alertRequest.title) },
|
||||
text = alertRequest.content
|
||||
)
|
||||
}
|
||||
}
|
@ -14,11 +14,17 @@ import com.pushdeer.os.ui.theme.MBlue
|
||||
|
||||
@ExperimentalMaterialApi
|
||||
@Composable
|
||||
fun SettingItem(text: String, buttonString: String, onItemClick:()->Unit={},onButtonClick: () -> Unit) {
|
||||
fun SettingItem(
|
||||
text: String,
|
||||
buttonString: String,
|
||||
onItemClick: () -> Unit = {},
|
||||
paddingValues: PaddingValues = PaddingValues(bottom = 16.dp),
|
||||
onButtonClick: () -> Unit
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 16.dp)
|
||||
.padding(paddingValues)
|
||||
) {
|
||||
CardItemWithContent(onClick = onItemClick) {
|
||||
Row(
|
||||
@ -51,4 +57,21 @@ fun SettingItem(text: String, buttonString: String, onItemClick:()->Unit={},onBu
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//@ExperimentalMaterialApi
|
||||
//@Composable
|
||||
//fun SettingItem(content: @Composable () -> Unit) {
|
||||
// Card(
|
||||
// onClick = onClick,
|
||||
// shape = RoundedCornerShape(4.dp),
|
||||
// modifier = Modifier
|
||||
// .border(
|
||||
// width = 1.dp,
|
||||
// color = MainBlue,
|
||||
// shape = RoundedCornerShape(4.dp)
|
||||
// ),
|
||||
// content = content,
|
||||
// elevation = 5.dp
|
||||
// )
|
||||
//}
|
@ -1,82 +1,110 @@
|
||||
package com.pushdeer.os.ui.compose.componment
|
||||
|
||||
import androidx.compose.animation.animateColorAsState
|
||||
import androidx.compose.animation.*
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ArrowBack
|
||||
import androidx.compose.material.icons.filled.Delete
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pushdeer.os.holder.RequestHolder
|
||||
import com.pushdeer.os.ui.theme.SwipeToDismissGray
|
||||
import com.pushdeer.os.ui.theme.SwipeToDismissRed
|
||||
import com.pushdeer.os.values.ConstValues
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@ExperimentalMaterialApi
|
||||
@Composable
|
||||
fun SwipeToDismissItem(
|
||||
onAction: () -> Unit,
|
||||
sidePadding: Boolean = false,
|
||||
requestHolder: RequestHolder,
|
||||
content: @Composable RowScope.() -> Unit
|
||||
) {
|
||||
val dismissState = rememberDismissState()
|
||||
if (dismissState.isDismissed(DismissDirection.EndToStart)) {
|
||||
onAction()
|
||||
var visible by remember {
|
||||
mutableStateOf(true)
|
||||
}
|
||||
Column(modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 16.dp)) {
|
||||
SwipeToDismiss(
|
||||
state = dismissState,
|
||||
background = {
|
||||
// val direction = dismissState.dismissDirection ?: return@SwipeToDismiss
|
||||
val dismissv = DismissValue.Default
|
||||
val dismissState = rememberDismissState(initialValue = dismissv)
|
||||
LaunchedEffect(Unit){
|
||||
if (dismissState.isDismissed(DismissDirection.EndToStart)){
|
||||
requestHolder.coroutineScope.launch {
|
||||
dismissState.reset()
|
||||
}
|
||||
}
|
||||
}
|
||||
AnimatedVisibility(
|
||||
visible = visible,
|
||||
enter = fadeIn() + expandVertically(),
|
||||
exit = fadeOut() + shrinkVertically()
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 16.dp)
|
||||
) {
|
||||
|
||||
val color by animateColorAsState(
|
||||
when (dismissState.targetValue) {
|
||||
DismissValue.DismissedToEnd -> Color.Green
|
||||
DismissValue.DismissedToStart -> Color.Red
|
||||
else -> Color.Gray
|
||||
}
|
||||
)
|
||||
SwipeToDismiss(
|
||||
state = dismissState,
|
||||
background = {
|
||||
|
||||
// val alignment = when (direction) {
|
||||
// DismissDirection.StartToEnd -> Alignment.CenterStart
|
||||
// DismissDirection.EndToStart -> Alignment.CenterEnd
|
||||
// }
|
||||
//
|
||||
// val icon = when (direction) {
|
||||
// DismissDirection.StartToEnd -> Icons.Default.Done
|
||||
// DismissDirection.EndToStart -> Icons.Default.Delete
|
||||
// }
|
||||
|
||||
val alignment = Alignment.CenterEnd
|
||||
val icon = Icons.Default.Delete
|
||||
|
||||
Box(
|
||||
contentAlignment = alignment,
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.clip(RoundedCornerShape(4.dp))
|
||||
.background(color)
|
||||
.padding(end = 32.dp)
|
||||
) {
|
||||
Icon(
|
||||
imageVector = icon,
|
||||
contentDescription = "",
|
||||
// tint = Color.Red
|
||||
val color by animateColorAsState(
|
||||
when (dismissState.targetValue) {
|
||||
DismissValue.DismissedToEnd -> SwipeToDismissGray
|
||||
DismissValue.DismissedToStart -> SwipeToDismissRed
|
||||
else -> SwipeToDismissGray
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
directions = setOf(DismissDirection.EndToStart),
|
||||
dismissThresholds = { direction ->
|
||||
FractionalThreshold(if (direction == DismissDirection.EndToStart) 0.45f else 0.57f)
|
||||
},
|
||||
dismissContent = content,
|
||||
modifier = Modifier.padding(horizontal = if (sidePadding) ConstValues.MainPageSidePadding else 0.dp)
|
||||
)
|
||||
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.clip(RoundedCornerShape(8.dp))
|
||||
.background(color)
|
||||
.padding(end = 32.dp),
|
||||
horizontalArrangement = Arrangement.End,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
IconButton(onClick = {
|
||||
requestHolder.coroutineScope.launch {
|
||||
dismissState.reset()
|
||||
}
|
||||
}) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.ArrowBack,
|
||||
contentDescription = "",
|
||||
)
|
||||
}
|
||||
IconButton(onClick = {
|
||||
visible = false
|
||||
|
||||
requestHolder.coroutineScope.launch {
|
||||
delay(300)
|
||||
onAction()
|
||||
}
|
||||
}) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.Delete,
|
||||
contentDescription = "",
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
directions = setOf(DismissDirection.EndToStart),
|
||||
dismissThresholds = {
|
||||
FractionalThreshold(0.45f)
|
||||
},
|
||||
dismissContent = content,
|
||||
modifier = Modifier.padding(horizontal = if (sidePadding) ConstValues.MainPageSidePadding else 0.dp)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
package com.pushdeer.os.ui.compose.componment
|
||||
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
import com.willowtreeapps.signinwithapplebutton.view.SignInWithAppleButton
|
||||
|
||||
@Composable
|
||||
fun WeChatLoginButton() {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.clip(RoundedCornerShape(4.dp))
|
||||
.border(BorderStroke(1.dp, color = Color.Green), shape = RoundedCornerShape(4.dp))
|
||||
.background(color = Color.Green)
|
||||
.width((150).dp)
|
||||
.height(38.dp)
|
||||
) {
|
||||
Text(text = "aaa")
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
fun W() {
|
||||
Row {
|
||||
WeChatLoginButton()
|
||||
AndroidView(factory = {
|
||||
SignInWithAppleButton(it)
|
||||
}, modifier = Modifier.border(1.dp, color = Color.Black, shape = RoundedCornerShape(4.dp)))
|
||||
}
|
||||
}
|
@ -1,37 +1,31 @@
|
||||
package com.pushdeer.os.ui.compose.page
|
||||
|
||||
import android.util.Log
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.Card
|
||||
import androidx.compose.material.ExperimentalMaterialApi
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
import com.pushdeer.os.R
|
||||
import com.pushdeer.os.holder.RequestHolder
|
||||
import com.willowtreeapps.signinwithapplebutton.SignInWithAppleConfiguration
|
||||
import com.willowtreeapps.signinwithapplebutton.SignInWithAppleResult
|
||||
import com.willowtreeapps.signinwithapplebutton.view.SignInWithAppleButton
|
||||
import kotlinx.coroutines.launch
|
||||
import com.pushdeer.os.ui.theme.MainGreen
|
||||
|
||||
@ExperimentalMaterialApi
|
||||
@Composable
|
||||
fun LoginPage(requestHolder: RequestHolder) {
|
||||
Box(modifier = Modifier.fillMaxSize()) {
|
||||
|
||||
val configuration = SignInWithAppleConfiguration.Builder()
|
||||
.clientId("com.pushdeer.site")
|
||||
.redirectUri("https://api2.pushdeer.com/callback/apple")
|
||||
.responseType(SignInWithAppleConfiguration.ResponseType.ALL)
|
||||
.scope(SignInWithAppleConfiguration.Scope.EMAIL)
|
||||
.build()
|
||||
|
||||
Image(
|
||||
painter = painterResource(R.drawable.logo_com_x2),
|
||||
contentDescription = "big push deer logo",
|
||||
@ -40,43 +34,50 @@ fun LoginPage(requestHolder: RequestHolder) {
|
||||
.align(Alignment.TopCenter)
|
||||
.padding(top = 50.dp)
|
||||
)
|
||||
AndroidView(
|
||||
factory = {
|
||||
SignInWithAppleButton(it).apply {
|
||||
setUpSignInWithAppleOnClick(
|
||||
requestHolder.fragmentManager,
|
||||
configuration
|
||||
) { result ->
|
||||
when (result) {
|
||||
is SignInWithAppleResult.Success -> {
|
||||
Log.d("WH_", "apple-id_token:${result.idToken}")
|
||||
requestHolder.coroutineScope.launch {
|
||||
requestHolder.pushDeerViewModel.login(result.idToken) {
|
||||
requestHolder.globalNavController.navigate("main") {
|
||||
requestHolder.globalNavController.popBackStack()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is SignInWithAppleResult.Failure -> {
|
||||
requestHolder.alert.alert("Warning Apple Id Login Failed", {
|
||||
result.error.message
|
||||
}, onOk = {})
|
||||
Log.d(
|
||||
"WH_",
|
||||
"Received error from Apple Sign In ${result.error.message}"
|
||||
)
|
||||
}
|
||||
is SignInWithAppleResult.Cancel -> {
|
||||
Log.d("WH_", "User canceled Apple Sign In")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Card(
|
||||
onClick = requestHolder.weChatLogin.login,
|
||||
shape = RoundedCornerShape(4.dp),
|
||||
modifier = Modifier
|
||||
.padding(bottom = 220.dp)
|
||||
.border(
|
||||
width = 1.dp,
|
||||
color = MainGreen,
|
||||
shape = RoundedCornerShape(4.dp)
|
||||
)
|
||||
.align(alignment = Alignment.BottomCenter)
|
||||
.padding(bottom = 100.dp)
|
||||
)
|
||||
|
||||
) {
|
||||
Text(
|
||||
text = "Sign in with WeChat",
|
||||
color = MainGreen,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier
|
||||
.padding(vertical = 16.dp)
|
||||
.fillMaxWidth(0.6F)
|
||||
)
|
||||
}
|
||||
|
||||
Card(
|
||||
onClick = requestHolder.appleLogin.login,
|
||||
shape = RoundedCornerShape(4.dp),
|
||||
modifier = Modifier
|
||||
.padding(bottom = 140.dp)
|
||||
.border(
|
||||
width = 1.dp,
|
||||
color = Color.Black,
|
||||
shape = RoundedCornerShape(4.dp)
|
||||
)
|
||||
.align(alignment = Alignment.BottomCenter)
|
||||
|
||||
) {
|
||||
Text(
|
||||
text = "Sign in with Apple",
|
||||
color = Color.Black,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier
|
||||
.padding(vertical = 16.dp)
|
||||
.fillMaxWidth(0.6F)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@ -72,12 +72,13 @@ fun DeviceListPage(requestHolder: RequestHolder) {
|
||||
val state = rememberLazyListState()
|
||||
LazyColumn(state = state) {
|
||||
items(
|
||||
items = requestHolder.pushDeerViewModel.deviceList,
|
||||
items = requestHolder.pushDeerViewModel.deviceList.sortedByDescending { it.id },
|
||||
key = { item: DeviceInfo -> item.id }) { deviceInfo: DeviceInfo ->
|
||||
var name by remember {
|
||||
mutableStateOf(deviceInfo.name)
|
||||
}
|
||||
SwipeToDismissItem(
|
||||
requestHolder = requestHolder,
|
||||
onAction = { requestHolder.device.deviceRemove(deviceInfo) }
|
||||
) {
|
||||
CardItemSingleLineWithIcon(
|
||||
|
@ -49,9 +49,11 @@ fun KeyListPage(requestHolder: RequestHolder) {
|
||||
}else{
|
||||
LazyColumn(modifier = Modifier.fillMaxWidth()) {
|
||||
items(
|
||||
requestHolder.pushDeerViewModel.keyList,
|
||||
requestHolder.pushDeerViewModel.keyList.sortedBy { it.id },
|
||||
key = { item: PushKey -> item.id }) { pushKey: PushKey ->
|
||||
SwipeToDismissItem(onAction = { requestHolder.key.remove(pushKey) }
|
||||
SwipeToDismissItem(
|
||||
requestHolder = requestHolder,
|
||||
onAction = { requestHolder.key.remove(pushKey) }
|
||||
) {
|
||||
KeyItem(key = pushKey, requestHolder = requestHolder)
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ fun MainPageFrame(
|
||||
titleStringId: Int,
|
||||
showSideIcon: Boolean = true,
|
||||
sideIcon: ImageVector = Icons.Default.Add,
|
||||
iconModifier: Modifier = Modifier,
|
||||
onSideIconClick: () -> Unit = {},
|
||||
sidePadding: Boolean = true,
|
||||
content: @Composable BoxScope.() -> Unit
|
||||
@ -53,7 +54,8 @@ fun MainPageFrame(
|
||||
Icon(
|
||||
imageVector = sideIcon,
|
||||
contentDescription = "",
|
||||
tint = Color.LightGray
|
||||
tint = Color.LightGray,
|
||||
modifier = iconModifier
|
||||
)
|
||||
}
|
||||
// }
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.pushdeer.os.ui.compose.page.main
|
||||
|
||||
import androidx.compose.animation.*
|
||||
import androidx.compose.animation.core.animateFloatAsState
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
@ -10,9 +11,9 @@ import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.KeyboardArrowDown
|
||||
import androidx.compose.material.icons.filled.KeyboardArrowUp
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.rotate
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
@ -37,9 +38,14 @@ fun MessageListPage(requestHolder: RequestHolder) {
|
||||
}
|
||||
}
|
||||
|
||||
// val a = rotat
|
||||
|
||||
val a by animateFloatAsState(targetValue = if (requestHolder.uiViewModel.showMessageSender) 0F else 180F)
|
||||
|
||||
MainPageFrame(
|
||||
titleStringId = Page.Messages.labelStringId,
|
||||
sideIcon = if (requestHolder.uiViewModel.showMessageSender) Icons.Default.KeyboardArrowUp else Icons.Default.KeyboardArrowDown,
|
||||
sideIcon = Icons.Default.KeyboardArrowDown,
|
||||
iconModifier = Modifier.rotate(a),
|
||||
onSideIconClick = { requestHolder.toggleMessageSender() },
|
||||
sidePadding = false
|
||||
) {
|
||||
@ -58,7 +64,7 @@ fun MessageListPage(requestHolder: RequestHolder) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 16.dp)
|
||||
.padding(bottom = 20.dp)
|
||||
.padding(horizontal = ConstValues.MainPageSidePadding)
|
||||
|
||||
) {
|
||||
@ -97,6 +103,7 @@ fun MessageListPage(requestHolder: RequestHolder) {
|
||||
items = messageList,
|
||||
key = { item: MessageEntity -> item.id }) { message: MessageEntity ->
|
||||
SwipeToDismissItem(
|
||||
requestHolder = requestHolder,
|
||||
onAction = {
|
||||
requestHolder.message.messageRemove(message.toMessage(), onDone = {
|
||||
requestHolder.messageViewModel.delete(message)
|
||||
|
@ -3,16 +3,32 @@ package com.pushdeer.os.ui.compose.page.main
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.util.Log
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.animation.*
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.Card
|
||||
import androidx.compose.material.ExperimentalMaterialApi
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pushdeer.os.R
|
||||
import com.pushdeer.os.data.api.data.response.UserInfo
|
||||
import com.pushdeer.os.holder.RequestHolder
|
||||
import com.pushdeer.os.ui.compose.componment.SettingItem
|
||||
import com.pushdeer.os.ui.navigation.Page
|
||||
import com.pushdeer.os.ui.theme.MainBlue
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@ExperimentalMaterialApi
|
||||
@Composable
|
||||
@ -21,51 +37,123 @@ fun SettingPage(requestHolder: RequestHolder) {
|
||||
titleStringId = Page.Settings.labelStringId,
|
||||
showSideIcon = false
|
||||
) {
|
||||
var showLoginMethod by remember {
|
||||
mutableStateOf(false)
|
||||
}
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
requestHolder.coroutineScope.launch {
|
||||
delay(300)
|
||||
showLoginMethod = true
|
||||
}
|
||||
}
|
||||
|
||||
LazyColumn(
|
||||
modifier = Modifier.fillMaxSize()
|
||||
) {
|
||||
item {
|
||||
// var newName by remember {
|
||||
// mutableStateOf(requestHolder.pushDeerViewModel.userInfo.name)
|
||||
// }
|
||||
SettingItem(
|
||||
text = "${stringResource(id = R.string.main_setting_user_hi)} ${requestHolder.pushDeerViewModel.userInfo.name} !",
|
||||
buttonString = stringResource(id = R.string.main_setting_user_logout),
|
||||
onItemClick = {
|
||||
|
||||
// requestHolder.alert.alert(
|
||||
// title = "修改用户名",
|
||||
// content = {
|
||||
// TextField(
|
||||
// value = newName,
|
||||
// onValueChange = { newName = it },
|
||||
// colors = TextFieldDefaults.textFieldColors(
|
||||
// focusedIndicatorColor = Color.Transparent,
|
||||
// unfocusedIndicatorColor = Color.Transparent,
|
||||
// disabledIndicatorColor = Color.Transparent,
|
||||
// errorIndicatorColor = Color.Transparent,
|
||||
// )
|
||||
// )
|
||||
// },
|
||||
// onOk = {
|
||||
//
|
||||
// }
|
||||
// )
|
||||
}
|
||||
Card(
|
||||
elevation = 5.dp,
|
||||
modifier = Modifier.padding(bottom = 16.dp),
|
||||
shape = RoundedCornerShape(8.dp),
|
||||
border = BorderStroke(1.dp, MainBlue)
|
||||
) {
|
||||
requestHolder.pushDeerViewModel.deviceList.filter { it.device_id == requestHolder.settingStore.thisDeviceId }
|
||||
.forEach {
|
||||
requestHolder.device.deviceRemove(it)
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
) {
|
||||
SettingItem(
|
||||
text = "${stringResource(id = R.string.main_setting_user_hi)} ${requestHolder.pushDeerViewModel.userInfo.name} !",
|
||||
buttonString = stringResource(id = R.string.main_setting_user_logout),
|
||||
paddingValues = PaddingValues(bottom = 0.dp),
|
||||
onItemClick = {}
|
||||
) {
|
||||
requestHolder.pushDeerViewModel.deviceList
|
||||
.filter { it.device_id == requestHolder.settingStore.thisDeviceId }
|
||||
.forEach { requestHolder.device.deviceRemove(it) }
|
||||
requestHolder.settingStore.userToken = ""
|
||||
requestHolder.globalNavController.navigate("login") {
|
||||
requestHolder.globalNavController.popBackStack()
|
||||
requestHolder.pushDeerViewModel.userInfo = UserInfo()
|
||||
}
|
||||
requestHolder.alert.alert(
|
||||
title = R.string.global_alert_title_alert,
|
||||
content = R.string.main_setting_alert_logout,
|
||||
onOk = {}
|
||||
)
|
||||
}
|
||||
AnimatedVisibility(
|
||||
visible = showLoginMethod,
|
||||
enter = fadeIn() + expandVertically(),
|
||||
exit = fadeOut() + shrinkVertically()
|
||||
) {
|
||||
|
||||
// LoginMethod Row
|
||||
Row(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 6.dp, start = 6.dp, end = 6.dp, top = 8.dp),
|
||||
horizontalArrangement = Arrangement.SpaceEvenly,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
|
||||
// wx 登陆按钮
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.SpaceEvenly,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier
|
||||
.weight(0.5F)
|
||||
.clickable {
|
||||
if (requestHolder.pushDeerViewModel.userInfo.isWeChatLogin) {
|
||||
requestHolder.alert.alert(
|
||||
title = "Hey",
|
||||
content = "你已经通过 微信账号 成功登陆咯!",
|
||||
onOk = {})
|
||||
} else {
|
||||
requestHolder.alert.alert(
|
||||
title = "绑定或迁移由 微信账号 创建的账号",
|
||||
content = "请注意,如果你将要登陆的 微信账号 已经在此登陆过,其设备列表将会与当前账号合并, PushKey 将会在合并时丢失。",
|
||||
onOk = requestHolder.weChatLogin.login
|
||||
)
|
||||
}
|
||||
}
|
||||
) {
|
||||
LoginMethod(
|
||||
isLogin = requestHolder.pushDeerViewModel.userInfo.isWeChatLogin,
|
||||
id = R.drawable.ic_wechat_colored
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
// apple 登陆按钮
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.SpaceEvenly,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier
|
||||
.weight(0.5F)
|
||||
.clickable {
|
||||
if (requestHolder.pushDeerViewModel.userInfo.isAppleLogin) {
|
||||
requestHolder.alert.alert(
|
||||
title = "Hey",
|
||||
content = "你已经通过 Apple Id 成功登陆咯!",
|
||||
onOk = {})
|
||||
} else {
|
||||
requestHolder.alert.alert(
|
||||
title = "绑定或迁移由 Apple Id 创建的账号",
|
||||
content = "请注意,如果你将要用来登陆 PushDeer 的 Apple Id 已经在此登陆过,其设备列表将会与当前账号合并, PushKey 将会在合并时丢失。",
|
||||
onOk = requestHolder.appleLogin.login
|
||||
)
|
||||
}
|
||||
}
|
||||
) {
|
||||
LoginMethod(
|
||||
isLogin = requestHolder.pushDeerViewModel.userInfo.isAppleLogin,
|
||||
id = R.drawable.ic_apple_colored
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
requestHolder.settingStore.userToken = ""
|
||||
requestHolder.globalNavController.navigate("login") {
|
||||
requestHolder.globalNavController.popBackStack()
|
||||
}
|
||||
requestHolder.alert.alert(
|
||||
R.string.global_alert_title_alert,
|
||||
R.string.main_setting_alert_logout,
|
||||
{}
|
||||
)
|
||||
}
|
||||
}
|
||||
// item {
|
||||
@ -81,7 +169,7 @@ fun SettingPage(requestHolder: RequestHolder) {
|
||||
text = stringResource(id = R.string.main_setting_douyoulike),
|
||||
buttonString = stringResource(id = R.string.main_setting_btn_like)
|
||||
) {
|
||||
val uri = Uri.parse("market://details?id=" + "com.pushdeer.os")
|
||||
val uri = Uri.parse("market://details?id=com.pushdeer.os")
|
||||
Intent(Intent.ACTION_VIEW, uri).apply {
|
||||
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
}.let {
|
||||
@ -107,12 +195,43 @@ fun SettingPage(requestHolder: RequestHolder) {
|
||||
}
|
||||
}
|
||||
|
||||
//@Composable
|
||||
//fun TogglePreferenceItem(label: String) {
|
||||
// Row(
|
||||
// verticalAlignment = Alignment.CenterVertically,
|
||||
// modifier = Modifier.fillMaxSize()
|
||||
// ) {
|
||||
// Text(text = label)
|
||||
// }
|
||||
//}
|
||||
@Composable
|
||||
fun IconYes() {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_okok2),
|
||||
contentDescription = "",
|
||||
tint = MainBlue,
|
||||
modifier = Modifier.size(20.dp)
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun IconNo() {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_okok2),
|
||||
contentDescription = "",
|
||||
tint = Color.Gray,
|
||||
modifier = Modifier.size(20.dp)
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun LoginMethod(isLogin: Boolean, @DrawableRes id: Int) {
|
||||
Row(
|
||||
modifier = Modifier.width(70.dp),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
if (isLogin)
|
||||
IconYes()
|
||||
else
|
||||
IconNo()
|
||||
Image(
|
||||
painter = painterResource(id = id),
|
||||
contentDescription = "",
|
||||
modifier = Modifier
|
||||
.padding(vertical = 12.dp)
|
||||
.size(35.dp),
|
||||
)
|
||||
}
|
||||
}
|
@ -9,4 +9,6 @@ val Teal200 = Color(0xFF03DAC5)
|
||||
|
||||
val MainBlue = Color(0xFF3B4789)
|
||||
val MainGreen = Color(0xFF296C05)
|
||||
val MainBottomBtn = Color(0xFF8E8E8E)
|
||||
val MainBottomBtn = Color(0xFF8E8E8E)
|
||||
val SwipeToDismissRed = Color(0x92FFF2F2)
|
||||
val SwipeToDismissGray = Color(0x92B6B6B6)
|
@ -30,25 +30,24 @@ class PushDeerViewModel(
|
||||
val keyList = mutableStateListOf<PushKey>()
|
||||
// var messageList = mutableStateListOf<Message>()
|
||||
|
||||
suspend fun login(idToken: String = "", onReturn: (String) -> Unit = {}) {
|
||||
suspend fun loginWithApple(idToken: String = "", onReturn: (String) -> Unit = {}) {
|
||||
withContext(Dispatchers.IO) {
|
||||
if (token == "" && idToken != "") {
|
||||
try {
|
||||
pushDeerService.loginIdToken(idToken).let {
|
||||
pushDeerService.loginWithAppleIdToken(idToken).let {
|
||||
it.content?.let { tokenOnly ->
|
||||
settingStore.userToken = tokenOnly.token
|
||||
token = tokenOnly.token
|
||||
Log.d(TAG, "login: $token")
|
||||
Log.d(TAG, "loginWithApple: $token")
|
||||
withContext(Dispatchers.Main) {
|
||||
onReturn.invoke(token)
|
||||
}
|
||||
}
|
||||
}
|
||||
logDogRepository.logi("login", "normally", "nothing happened")
|
||||
logDogRepository.logi("loginWithApple", "withAppleId", "nothing happened")
|
||||
} catch (e: Exception) {
|
||||
Log.d(TAG, "login: ${e.localizedMessage}")
|
||||
logDogRepository.loge("login", "", e.toString())
|
||||
return@withContext
|
||||
Log.d(TAG, "loginWithApple: ${e.localizedMessage}")
|
||||
logDogRepository.loge("loginWithApple", "", e.toString())
|
||||
}
|
||||
} else if (token == "" && idToken == "") {
|
||||
return@withContext
|
||||
@ -60,10 +59,50 @@ class PushDeerViewModel(
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun loginWithWeiXin(code:String,onReturn: (String) -> Unit){
|
||||
withContext(Dispatchers.IO){
|
||||
try {
|
||||
pushDeerService.loginWithWeXin(code).let {
|
||||
it.content?.let { tokenOnly ->
|
||||
settingStore.userToken = tokenOnly.token
|
||||
token = tokenOnly.token
|
||||
Log.d(TAG, "loginWithWeiXin: $token")
|
||||
withContext(Dispatchers.Main) {
|
||||
onReturn.invoke(token)
|
||||
}
|
||||
}
|
||||
}
|
||||
logDogRepository.logi("loginWithWeiXin", "withWeiXin", "nothing happened")
|
||||
}catch (e: Exception){
|
||||
Log.e(TAG, "loginWithWeiXin: ${e.localizedMessage}")
|
||||
logDogRepository.loge("loginWithWeiXin", "", e.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun userMerge(type:String,tokenorcode:String,onReturn: (String) -> Unit={}){
|
||||
Log.d("WH_", ": token:${token} type:${type} tokenorcode:${tokenorcode}")
|
||||
|
||||
withContext(Dispatchers.IO){
|
||||
try {
|
||||
pushDeerService.userMerge(token,type,tokenorcode).let {
|
||||
Log.d(TAG, "userMerge: $it")
|
||||
withContext(Dispatchers.Main){
|
||||
onReturn("")
|
||||
}
|
||||
}
|
||||
}catch (e: Exception) {
|
||||
Log.e(TAG, "userMerge:e ${e.localizedMessage}")
|
||||
logDogRepository.loge("userMerge", "", e.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun userInfo(onOk: (UserInfo) -> Unit = {}, onFailed: () -> Unit = {}) {
|
||||
withContext(Dispatchers.IO) {
|
||||
try {
|
||||
pushDeerService.userInfo(token).let {
|
||||
Log.d(TAG, "userInfo: ${it.content}")
|
||||
it.content?.let { ita ->
|
||||
userInfo = ita
|
||||
withContext(Dispatchers.Main) {
|
||||
|
@ -0,0 +1,69 @@
|
||||
package com.pushdeer.os.wxapi
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import com.pushdeer.os.App
|
||||
import com.tencent.mm.opensdk.modelbase.BaseReq
|
||||
import com.tencent.mm.opensdk.modelbase.BaseResp
|
||||
import com.tencent.mm.opensdk.modelmsg.SendAuth
|
||||
import com.tencent.mm.opensdk.openapi.IWXAPI
|
||||
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler
|
||||
|
||||
|
||||
class WXEntryActivity : Activity(), IWXAPIEventHandler {
|
||||
|
||||
companion object {
|
||||
const val CODE_KEY = "code"
|
||||
const val ACTION_RETURN_CODE = "return-code"
|
||||
}
|
||||
|
||||
private val iwxapi: IWXAPI by lazy { (application as App).iwxapi }
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
iwxapi.handleIntent(intent, this);
|
||||
}
|
||||
|
||||
// 微信发送的请求
|
||||
override fun onReq(p0: BaseReq?) {
|
||||
|
||||
}
|
||||
|
||||
// 发送到微信请求的响应结果
|
||||
override fun onResp(p0: BaseResp?) {
|
||||
when (p0?.errCode) {
|
||||
BaseResp.ErrCode.ERR_AUTH_DENIED, BaseResp.ErrCode.ERR_USER_CANCEL ->
|
||||
// if (RETURN_MSG_TYPE_SHARE === resp.getType()) {
|
||||
// Toast.makeText(this, "分享失败", Toast.LENGTH_SHORT).show()
|
||||
// } else {
|
||||
Toast.makeText(this, "登录失败", Toast.LENGTH_SHORT).show()
|
||||
// }
|
||||
BaseResp.ErrCode.ERR_OK -> when (p0.type) {
|
||||
1 -> {
|
||||
// login
|
||||
val code: String = (p0 as SendAuth.Resp).code
|
||||
code.let {
|
||||
sendBroadcast(Intent().apply {
|
||||
putExtra(CODE_KEY, code)
|
||||
action = ACTION_RETURN_CODE
|
||||
})
|
||||
Log.d("WH_", "onResp: $code")
|
||||
finish()
|
||||
}
|
||||
}
|
||||
// RETURN_MSG_TYPE_LOGIN -> //拿到了微信返回的code,立马再去请求access_token
|
||||
// var code
|
||||
// : String
|
||||
// ?
|
||||
// = (resp as SendAuth.Resp).code
|
||||
// RETURN_MSG_TYPE_SHARE -> {
|
||||
// Toast.makeText(this, "微信分享成功", Toast.LENGTH_SHORT).show()
|
||||
// finish()
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 139 KiB |
9
android/app/src/main/res/drawable/ic_apple_colored.xml
Normal file
9
android/app/src/main/res/drawable/ic_apple_colored.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="33.9dp"
|
||||
android:height="36.991dp"
|
||||
android:viewportWidth="33.9"
|
||||
android:viewportHeight="36.991">
|
||||
<path
|
||||
android:pathData="M10.934,36.986c-2.372,0 -4.859,-1.735 -7.289,-5.149 -2.43,-3.529 -3.645,-6.942 -3.645,-10.182a10.774,10.774 0,0 1,2.835 -7.694,8.994 8.994,0 0,1 6.826,-2.835 19.017,19.017 0,0 1,4.223 0.578,13.923 13.923,0 0,0 3.355,0.578 13.4,13.4 0,0 0,3.413 -0.694,15.208 15.208,0 0,1 4.165,-0.694 9.788,9.788 0,0 1,5.091 1.273,10.853 10.853,0 0,1 1.62,1.157L32.916,14.486 31.47,15.586a12.067,12.067 0,0 0,-1.735 1.62,5.859 5.859,0 0,0 -1.446,3.7A6.523,6.523 0,0 0,29.85 25.016a7.144,7.144 0,0 0,2.719 2.025l1.331,0.578 -0.578,1.331a18.746,18.746 0,0 1,-2.6 4.107c-2.083,2.6 -4.165,3.934 -6.19,3.934a13.777,13.777 0,0 1,-3.3 -0.636,13.421 13.421,0 0,0 -3.645,-0.636 11.316,11.316 0,0 0,-3.413 0.636A11.678,11.678 0,0 1,10.934 36.986ZM9.661,14.025a6.332,6.332 0,0 0,-4.744 1.967,7.9 7.9,0 0,0 -2.025,5.669 15.293,15.293 0,0 0,3.124 8.5c1.735,2.488 3.529,3.934 4.917,3.934a6.836,6.836 0,0 0,2.2 -0.521,14.218 14.218,0 0,1 4.4,-0.81 15,15 0,0 1,4.512 0.752,12.512 12.512,0 0,0 2.488,0.521c1.1,0 2.488,-0.983 3.934,-2.835a13.211,13.211 0,0 0,1.562 -2.256,11.955 11.955,0 0,1 -2.43,-2.14 9.342,9.342 0,0 1,-2.2 -5.9,8.511 8.511,0 0,1 2.083,-5.554 9.219,9.219 0,0 1,0.752 -0.752,7.076 7.076,0 0,0 -3.413,-0.752 11.639,11.639 0,0 0,-3.355 0.578,17.3 17.3,0 0,1 -4.223,0.81 16.292,16.292 0,0 1,-3.992 -0.636,12.183 12.183,0 0,0 -3.587,-0.578ZM17.355,9.802a3.161,3.161 0,0 1,-2.2 -0.926,2.417 2.417,0 0,1 -0.578,-2.2c0.578,-2.372 1.331,-3.876 2.372,-4.686l0.058,-0.058A12.262,12.262 0,0 1,22.677 0.025a2.852,2.852 0,0 1,2.488 0.868,2.385 2.385,0 0,1 0.694,2.083 7.988,7.988 0,0 1,-2.545 4.975l-0.058,0.058a12.444,12.444 0,0 1,-5.322 1.793ZM17.413,7.372ZM18.743,4.186a5.55,5.55 0,0 0,-1.215 2.661,11.137 11.137,0 0,0 3.934,-1.273 4.928,4.928 0,0 0,1.388 -2.719A10.286,10.286 0,0 0,18.743 4.186Z"
|
||||
android:fillColor="#3b4789"/>
|
||||
</vector>
|
@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="76dp"
|
||||
android:height="76dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M950.14,827.09L73.86,827.09a73.81,73.81 0,0 1,-73.81 -73.81L0.04,270.72a73.81,73.81 0,0 1,73.81 -73.81h876.29a73.81,73.81 0,0 1,73.81 73.81v482.47a73.81,73.81 0,0 1,-73.81 73.86zM246.14,679.38v-192l98.47,123.09 98.43,-123.09v192h98.47L541.53,344.66h-98.47l-98.43,123.09 -98.47,-123.09L147.67,344.66v334.81zM905.86,512h-98.47L807.38,344.62h-98.43L708.95,512h-98.47l147.67,172.33z"/>
|
||||
</vector>
|
9
android/app/src/main/res/drawable/ic_okok2.xml
Normal file
9
android/app/src/main/res/drawable/ic_okok2.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="76dp"
|
||||
android:height="76dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M512,321.5c105.22,0 190.5,85.29 190.5,190.5 0,105.22 -85.28,190.5 -190.5,190.5S321.5,617.22 321.5,512C321.5,406.79 406.78,321.5 512,321.5z"/>
|
||||
</vector>
|
15
android/app/src/main/res/drawable/ic_wechat_colored.xml
Normal file
15
android/app/src/main/res/drawable/ic_wechat_colored.xml
Normal file
@ -0,0 +1,15 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="44.557dp"
|
||||
android:height="36.991dp"
|
||||
android:viewportWidth="44.557"
|
||||
android:viewportHeight="36.991">
|
||||
<path
|
||||
android:pathData="M27.149,20.122a1.348,1.348 0,1 1,-1.346 -1.282,1.348 1.348,0 0,1 1.346,1.282m9.342,0A1.348,1.348 0,1 1,35.149 18.777a1.348,1.348 0,0 1,1.348 1.348"
|
||||
android:fillColor="#3b4789"/>
|
||||
<path
|
||||
android:pathData="M33.763,35.115l-0.253,0.055q-0.352,0.075 -0.706,0.139a10.942,10.942 0,0 1,-2.43 0.233c-6.374,-0.211 -11.341,-3.337 -13.33,-8.3q-0.138,-0.36 -0.259,-0.726l-0.075,-0.23q-0.082,-0.257 -0.146,-0.518a12.867,12.867 0,0 1,-0.35 -2.874c0,-6.493 5.962,-11.616 13.453,-11.95l0.337,-0.026c0.3,-0.023 0.493,-0.032 0.713,-0.032h0.561l0.353,0.006c7.145,0.557 12.925,5.949 12.925,12.3 0,2.975 -1.474,5.913 -4.164,8.441q-0.133,0.124 -0.269,0.243l0.379,2.7a1.866,1.866 0,0 1,-2.625 2.22L34.129,35.024q-0.179,0.045 -0.36,0.087ZM42.123,23.191c0,-5 -4.731,-9.416 -10.6,-9.876h-0.807c-0.143,0 -0.292,0 -0.531,0.023l-0.405,0.029c-6.3,0.282 -11.137,4.446 -11.137,9.526a10.377,10.377 0,0 0,0.285 2.31c0.023,0.094 0.055,0.214 0.1,0.35l0.065,0.188c0.081,0.25 0.162,0.48 0.214,0.606 1.607,4.015 5.693,6.584 11.153,6.766a8.767,8.767 0,0 0,1.912 -0.194q0.317,-0.057 0.632,-0.123l0.214,-0.049c0.178,-0.042 0.321,-0.075 0.736,-0.181a1.215,1.215 0,0 1,0.813 0.081l3.237,1.523 -0.379,-2.631a1.215,1.215 0,0 1,0.528 -1.186c0.045,-0.032 0.327,-0.262 0.577,-0.5 2.229,-2.1 3.4,-4.42 3.4,-6.668ZM0,14.157c0,-7.848 7.355,-14.157 16.318,-14.157 7.913,0 14.97,4.948 16.4,11.623a1.79,1.79 0,0 1,0.019 0.642,1.215 1.215,0 0,1 -2.417,-0.227c-1.225,-5.437 -7.213,-9.607 -14,-9.607 -7.7,0 -13.888,5.308 -13.888,11.73 0,3.415 1.753,6.513 5.165,9.021A1.215,1.215 0,0 1,8.029 24.542l-0.885,2.657L11.129,25.342a1.215,1.215 0,0 1,0.852 -0.065l0.207,0.065a18.4,18.4 0,0 0,4.128 0.551,7.624 7.624,0 0,0 1.225,-0.152 0.289,0.289 0,0 0,-0.1 0.058,1.257 1.257,0 0,1 1.491,0.042 1.215,1.215 0,0 1,0.2 1.708c-0.447,0.564 -1.8,0.771 -2.819,0.771a19.833,19.833 0,0 1,-4.553 -0.59l-4.715,2.2A1.879,1.879 0,0 1,4.429 27.662l1.021,-3.062c-3.551,-2.868 -5.45,-6.464 -5.45,-10.443Z"
|
||||
android:fillColor="#3b4789"/>
|
||||
<path
|
||||
android:pathData="M12.592,9.455a1.685,1.685 0,1 1,-1.685 -1.682,1.685 1.685,0 0,1 1.685,1.682m11.088,0a1.685,1.685 0,1 1,-1.685 -1.682,1.685 1.685,0 0,1 1.685,1.682"
|
||||
android:fillColor="#3b4789"/>
|
||||
</vector>
|
@ -29,4 +29,5 @@
|
||||
<string name="main_setting_douyoulike">喜欢 PushDeer 吗?</string>
|
||||
<string name="main_setting_btn_like">喜欢</string>
|
||||
<string name="main_setting_alert_logout">由于厂商推送设备服务限制,暂时不支持更换为自建 PushDeer 服务器,但仅更换登陆账号并不会影响您的使用。</string>
|
||||
<string name="global_swipetodismiss_alert_delete">确定删除?</string>
|
||||
</resources>
|
@ -28,4 +28,5 @@
|
||||
<string name="main_setting_douyoulike">Do you line PushDeer?</string>
|
||||
<string name="main_setting_btn_like">Like</string>
|
||||
<string name="main_setting_alert_logout">Due to the limitations of the vendor\'s push device service, it is not supported to change to the self-built PushDeer server for the time being, but only changing the login account will not affect your use.</string>
|
||||
<string name="global_swipetodismiss_alert_delete">Delete?</string>
|
||||
</resources>
|
||||
|
Loading…
Reference in New Issue
Block a user