mirror of
https://github.com/easychen/pushdeer.git
synced 2024-11-01 08:09:19 +08:00
Merge branch 'main' of https://github.com/easychen/pushdeer into main
This commit is contained in:
commit
93024fd028
@ -13,6 +13,7 @@
|
||||
<entry key="../../../../layout/compose-model-1641659551303.xml" value="2.0" />
|
||||
<entry key="../../../../layout/compose-model-1641659962289.xml" value="2.0" />
|
||||
<entry key="../../../../layout/compose-model-1641694023752.xml" value="0.1" />
|
||||
<entry key="../../../../layout/compose-model-1642733328920.xml" value="2.0" />
|
||||
<entry key="app/src/main/res/drawable/fragment_qr_scan.xml" value="0.12314814814814815" />
|
||||
<entry key="app/src/main/res/drawable/ic_markdown.xml" value="0.12962962962962962" />
|
||||
</map>
|
||||
|
@ -7,11 +7,12 @@
|
||||
* MiPush(状态:已调通、已接入)
|
||||
* miui 12.5.6 正常
|
||||
* 原生、类原生 可成功注册,无法收到推送,可能和地区识别有关,待解决
|
||||
* miui下处于"几乎可用"的状态,已接入 appleId
|
||||
|
||||
### TODO
|
||||
|
||||
* ~~调通 MiPush~~
|
||||
* 接入 MiPush
|
||||
* ~~接入 MiPush~~
|
||||
* 完善 log ~~采集~~ 回传机制,便于调试
|
||||
* 测试不同厂商设备上的通知推送效果
|
||||
* ~~接入 PushDeer~~
|
||||
@ -21,6 +22,11 @@
|
||||
* ~~增加侧滑手势相关动作~~
|
||||
* 增加各种操作前的二次确认弹窗,包括自动登陆
|
||||
* 增加非Miui设备的权限获取
|
||||
* 增加手动修改服务器地址/退出登陆的逻辑(并放置到登陆界面)
|
||||
* 增加登陆过程中的图形提示
|
||||
* 增加对PushKey重命名的逻辑
|
||||
* 增加对设备重命名的逻辑
|
||||
* 增加长按复制消息内容的逻辑
|
||||
|
||||
### 日志
|
||||
|
||||
@ -88,6 +94,19 @@
|
||||
* 调整项目文件结构
|
||||
* 将数据库用作message列表的直接数据来源
|
||||
|
||||
* 2022-01-20
|
||||
* 修改 /device/reg post参数增加 type=android
|
||||
* 集成 SignIn With Apple
|
||||
* 调整设备列表加号的显示和操作逻辑
|
||||
* 将自动注册设备修改为手动点击加号注册设备
|
||||
* 当前app几乎处于可以使用的状态
|
||||
|
||||
* 2022-01-21
|
||||
* 修改登陆界面ui
|
||||
* 增加key/device的重命名逻辑
|
||||
* 适配英语和中文
|
||||
|
||||
|
||||
### 感谢
|
||||
|
||||
https://github.com/taoweiji/MixPush
|
@ -9,7 +9,7 @@ android {
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.pushdeer.os"
|
||||
minSdk 21
|
||||
minSdk 22
|
||||
targetSdk 31
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
@ -106,6 +106,8 @@ dependencies {
|
||||
implementation "io.noties.markwon:html:$markwon_version"
|
||||
|
||||
implementation "io.coil-kt:coil:1.4.0"
|
||||
|
||||
implementation 'com.github.vishalkumarsinghvi:sign-in-with-apple-button-android:0.6'
|
||||
// implementation 'com.github.bumptech.glide:glide:4.12.0'
|
||||
// annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
|
||||
}
|
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": 1,
|
||||
"versionName": "1.0",
|
||||
"outputFile": "app-debug.apk"
|
||||
}
|
||||
],
|
||||
"elementType": "File"
|
||||
}
|
BIN
android/app/debug/pushdeer-for-android-v1.0.apk
Normal file
BIN
android/app/debug/pushdeer-for-android-v1.0.apk
Normal file
Binary file not shown.
@ -24,7 +24,7 @@ class App : Application() {
|
||||
val repositoryKeeper by lazy { RepositoryKeeper(database) }
|
||||
val pushDeerService by lazy {
|
||||
Retrofit.Builder()
|
||||
.baseUrl("http://0.0.0.0:8800")
|
||||
.baseUrl(PushDeerApi.baseUrl)
|
||||
.addConverterFactory(ScalarsConverterFactory.create())
|
||||
.addConverterFactory(GsonConverterFactory.create())
|
||||
.build()
|
||||
@ -45,7 +45,7 @@ class App : Application() {
|
||||
MiPushClient.registerPush(this, AppKeys.MiPush_Id, AppKeys.MiPush_Key)
|
||||
}
|
||||
//打开Log
|
||||
val newLogger: LoggerInterface = object : LoggerInterface {
|
||||
Logger.setLogger(this, object : LoggerInterface {
|
||||
override fun setTag(tag: String) {
|
||||
// ignore
|
||||
}
|
||||
@ -57,8 +57,7 @@ class App : Application() {
|
||||
override fun log(content: String) {
|
||||
Log.d(TAG, content)
|
||||
}
|
||||
}
|
||||
Logger.setLogger(this, newLogger)
|
||||
})
|
||||
}
|
||||
|
||||
private fun shouldInit(): Boolean {
|
||||
|
@ -11,6 +11,7 @@ import androidx.activity.compose.setContent
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.compose.animation.ExperimentalAnimationApi
|
||||
import androidx.compose.material.ExperimentalMaterialApi
|
||||
import androidx.compose.material.MaterialTheme
|
||||
@ -19,6 +20,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.navigation.NavHostController
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
@ -28,10 +30,10 @@ import com.google.accompanist.insets.ProvideWindowInsets
|
||||
import com.google.accompanist.insets.statusBarsPadding
|
||||
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||
import com.pushdeer.os.activity.QrScanActivity
|
||||
import com.pushdeer.os.data.api.data.request.DeviceInfo
|
||||
import com.pushdeer.os.holder.RequestHolder
|
||||
import com.pushdeer.os.store.SettingStore
|
||||
import com.pushdeer.os.ui.compose.page.LogDaoPage
|
||||
import com.pushdeer.os.ui.compose.componment.MyAlertDialog
|
||||
import com.pushdeer.os.ui.compose.page.LogDogPage
|
||||
import com.pushdeer.os.ui.compose.page.LoginPage
|
||||
import com.pushdeer.os.ui.compose.page.main.MainPage
|
||||
import com.pushdeer.os.ui.theme.PushDeerTheme
|
||||
@ -49,7 +51,7 @@ import kotlinx.coroutines.launch
|
||||
import java.util.*
|
||||
|
||||
|
||||
class MainActivity : ComponentActivity(), RequestHolder {
|
||||
class MainActivity : AppCompatActivity(), RequestHolder {
|
||||
|
||||
private val viewModelFactory by lazy { (application as App).viewModelFactory }
|
||||
private val repositoryKeeper by lazy { (application as App).repositoryKeeper }
|
||||
@ -59,6 +61,8 @@ class MainActivity : ComponentActivity(), 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 resource: Resources by lazy { this.resource }
|
||||
|
||||
override val coilImageLoader: ImageLoader by lazy {
|
||||
ImageLoader.Builder(this)
|
||||
@ -69,6 +73,7 @@ class MainActivity : ComponentActivity(), RequestHolder {
|
||||
}
|
||||
.build()
|
||||
}
|
||||
override val alert: RequestHolder.AlertRequest by lazy { object : RequestHolder.AlertRequest(resources) {} }
|
||||
|
||||
override val markdown: Markwon by lazy {
|
||||
Markwon.builder(this)
|
||||
@ -106,40 +111,22 @@ class MainActivity : ComponentActivity(), RequestHolder {
|
||||
val useDarkIcons = MaterialTheme.colors.isLight
|
||||
val systemUiController = rememberSystemUiController()
|
||||
when {
|
||||
SystemUtil.isMiui() -> {
|
||||
systemUiController.setStatusBarColor(Color.Transparent, useDarkIcons)
|
||||
}
|
||||
else -> {
|
||||
systemUiController.setSystemBarsColor(Color.Transparent, useDarkIcons)
|
||||
}
|
||||
SystemUtil.isMiui() -> systemUiController.setStatusBarColor(Color.Transparent, useDarkIcons)
|
||||
else -> systemUiController.setSystemBarsColor(Color.Transparent, useDarkIcons)
|
||||
}
|
||||
WindowCompat.setDecorFitsSystemWindows(window, true)
|
||||
miPushRepository.regId.observe(this) {
|
||||
// 这个操作放到注册成功后进行
|
||||
settingStore.thisDeviceId = it
|
||||
coroutineScope.launch {
|
||||
if (pushDeerViewModel.shouldRegDevice()) {
|
||||
pushDeerViewModel.deviceReg(DeviceInfo().apply {
|
||||
this.name = SystemUtil.getDeviceModel()
|
||||
this.device_id = it
|
||||
this.is_clip = 0
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SideEffect {
|
||||
coroutineScope.launch {
|
||||
pushDeerViewModel.login().also {
|
||||
pushDeerViewModel.userInfo()
|
||||
pushDeerViewModel.keyList()
|
||||
pushDeerViewModel.deviceList()
|
||||
pushDeerViewModel.messageList()
|
||||
|
||||
pushDeerViewModel.login(onReturn = {
|
||||
globalNavController.navigate("main") {
|
||||
globalNavController.popBackStack()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -155,13 +142,14 @@ class MainActivity : ComponentActivity(), RequestHolder {
|
||||
LoginPage(requestHolder = this@MainActivity)
|
||||
}
|
||||
composable("logdog") {
|
||||
LogDaoPage(requestHolder = this@MainActivity)
|
||||
LogDogPage(requestHolder = this@MainActivity)
|
||||
}
|
||||
composable("main") {
|
||||
MainPage(requestHolder = this@MainActivity)
|
||||
}
|
||||
}
|
||||
}
|
||||
MyAlertDialog(alertRequest = alert)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,22 @@
|
||||
package com.pushdeer.os.data.api
|
||||
|
||||
import com.pushdeer.os.data.api.data.response.*
|
||||
import retrofit2.http.*
|
||||
import retrofit2.http.Field
|
||||
import retrofit2.http.FieldMap
|
||||
import retrofit2.http.FormUrlEncoded
|
||||
import retrofit2.http.POST
|
||||
|
||||
interface PushDeerApi {
|
||||
@GET("/login/fake")
|
||||
suspend fun fakeLogin(): ReturnData<TokenOnly>
|
||||
companion object {
|
||||
val baseUrl = "https://api2.pushdeer.com"
|
||||
}
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST("/login/idtoken")
|
||||
suspend fun loginIdToken(@Field("idToken") idToken: String): ReturnData<TokenOnly>
|
||||
|
||||
// @GET("/login/fake")
|
||||
// suspend fun fakeLogin(): ReturnData<TokenOnly>
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST("/user/info")
|
||||
@ -21,7 +32,15 @@ interface PushDeerApi {
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST("/device/remove")
|
||||
suspend fun deviceRemove(@Field("token") token: String,@Field("id") id:Int): String
|
||||
suspend fun deviceRemove(@Field("token") token: String, @Field("id") id: Int): String
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST("/device/rename")
|
||||
suspend fun deviceRename(
|
||||
@Field("token") token: String,
|
||||
@Field("id") id: Int,
|
||||
@Field("name") newName: String
|
||||
): String
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST("/key/gen")
|
||||
@ -39,6 +58,14 @@ interface PushDeerApi {
|
||||
@POST("/key/remove")
|
||||
suspend fun keyRemove(@FieldMap data: Map<String, String>): String
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST("/key/rename")
|
||||
suspend fun keyRename(
|
||||
@Field("token") token: String,
|
||||
@Field("id") id: String,
|
||||
@Field("name") newName: String
|
||||
): String
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST("/message/push")
|
||||
suspend fun messagePush(@FieldMap data: Map<String, String>): String
|
||||
@ -49,5 +76,5 @@ interface PushDeerApi {
|
||||
|
||||
@FormUrlEncoded
|
||||
@POST("/message/remove")
|
||||
suspend fun messageRemove(@Field("token")token:String,@Field("id")id:Int): String
|
||||
suspend fun messageRemove(@Field("token") token: String, @Field("id") id: Int): String
|
||||
}
|
@ -13,7 +13,8 @@ class DeviceInfo {
|
||||
"token" to token,
|
||||
"name" to name,
|
||||
"device_id" to device_id,
|
||||
"is_clip" to is_clip.toString()
|
||||
"is_clip" to is_clip.toString(),
|
||||
"type" to "android"
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1,13 +0,0 @@
|
||||
package com.pushdeer.os.data.api.data.response
|
||||
|
||||
class DeviceRemove {
|
||||
var token: String = ""
|
||||
var id = ""
|
||||
|
||||
fun toMap():Map<String,String> {
|
||||
return mapOf(
|
||||
"token" to token,
|
||||
"id" to id
|
||||
)
|
||||
}
|
||||
}
|
@ -10,6 +10,7 @@ class Message : MessageEntity() {
|
||||
this.text = this@Message.text
|
||||
this.desp = this@Message.desp
|
||||
this.type = this@Message.type
|
||||
this.pushkey_name = this@Message.pushkey_name
|
||||
this.created_at = this@Message.created_at
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ public class MessageEntity {
|
||||
public String text;
|
||||
public String desp;
|
||||
public String type;
|
||||
public String pushkey_name;
|
||||
public String created_at;
|
||||
|
||||
|
||||
@ -20,10 +21,11 @@ public class MessageEntity {
|
||||
Message m = new Message();
|
||||
m.id = id;
|
||||
m.uid = uid;
|
||||
m.created_at = created_at;
|
||||
m.desp = desp;
|
||||
m.text = text;
|
||||
m.desp = desp;
|
||||
m.type = type;
|
||||
m.pushkey_name = pushkey_name;
|
||||
m.created_at = created_at;
|
||||
return m;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +0,0 @@
|
||||
package com.pushdeer.os.holder
|
||||
|
||||
interface DataHolder {
|
||||
}
|
@ -3,11 +3,18 @@ package com.pushdeer.os.holder
|
||||
import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
import android.content.Intent
|
||||
import android.util.Log
|
||||
import android.content.res.Resources
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.navigation.NavHostController
|
||||
import coil.ImageLoader
|
||||
import com.pushdeer.os.R
|
||||
import com.pushdeer.os.activity.QrScanActivity
|
||||
import com.pushdeer.os.data.api.data.request.DeviceInfo
|
||||
import com.pushdeer.os.data.api.data.response.Message
|
||||
@ -26,7 +33,7 @@ interface RequestHolder {
|
||||
val uiViewModel: UiViewModel
|
||||
val pushDeerViewModel: PushDeerViewModel
|
||||
val logDogViewModel: LogDogViewModel
|
||||
val messageViewModel:MessageViewModel
|
||||
val messageViewModel: MessageViewModel
|
||||
val settingStore: SettingStore
|
||||
val globalNavController: NavHostController
|
||||
val coroutineScope: CoroutineScope
|
||||
@ -35,6 +42,12 @@ interface RequestHolder {
|
||||
val activityOpener: ActivityResultLauncher<Intent>
|
||||
val coilImageLoader: ImageLoader
|
||||
|
||||
// val resource:Resources
|
||||
|
||||
val fragmentManager: FragmentManager
|
||||
|
||||
val alert: AlertRequest
|
||||
|
||||
val clipboardManager: ClipboardManager
|
||||
|
||||
fun copyPlainString(str: String) {
|
||||
@ -64,7 +77,17 @@ interface RequestHolder {
|
||||
}
|
||||
}
|
||||
|
||||
fun deviceReg(deviceInfo: DeviceInfo){
|
||||
fun keyRename(pushKey: PushKey){
|
||||
coroutineScope.launch {
|
||||
pushDeerViewModel.keyRename(pushKey){
|
||||
coroutineScope.launch {
|
||||
pushDeerViewModel.keyList()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun deviceReg(deviceInfo: DeviceInfo) {
|
||||
coroutineScope.launch {
|
||||
pushDeerViewModel.deviceReg(deviceInfo)
|
||||
}
|
||||
@ -77,24 +100,38 @@ interface RequestHolder {
|
||||
}
|
||||
}
|
||||
|
||||
fun deviceRename(deviceInfo: DeviceInfo) {
|
||||
coroutineScope.launch {
|
||||
pushDeerViewModel.deviceRename(deviceInfo) {
|
||||
coroutineScope.launch {
|
||||
pushDeerViewModel.deviceList()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun messagePush(text: String, desp: String, type: String, pushkey: String) {
|
||||
coroutineScope.launch {
|
||||
pushDeerViewModel.messagePush(text, desp, type, pushkey)
|
||||
}
|
||||
}
|
||||
|
||||
fun messagePushTest(desp: String) {
|
||||
fun messagePushTest(text: String) {
|
||||
if (pushDeerViewModel.keyList.isNotEmpty()) {
|
||||
messagePush("pushtest", desp, "markdown", pushDeerViewModel.keyList[0].key)
|
||||
messagePush(text, "pushtest", "markdown", pushDeerViewModel.keyList[0].key)
|
||||
coroutineScope.launch {
|
||||
delay(1000)
|
||||
pushDeerViewModel.messageList()
|
||||
}
|
||||
} else
|
||||
Log.d("WH_", "messagePushTest: keylist is empty")
|
||||
} else {
|
||||
alert.alert(
|
||||
R.string.global_alert_title_alert,
|
||||
R.string.main_message_send_alert,
|
||||
onOk = {})
|
||||
}
|
||||
}
|
||||
|
||||
fun messageRemove(message: Message,onDone:()->Unit={}) {
|
||||
fun messageRemove(message: Message, onDone: () -> Unit = {}) {
|
||||
coroutineScope.launch {
|
||||
// pushDeerViewModel.messageList.remove(message)
|
||||
pushDeerViewModel.messageRemove(message.id)
|
||||
@ -112,4 +149,48 @@ interface RequestHolder {
|
||||
logDogViewModel.clear()
|
||||
}
|
||||
}
|
||||
|
||||
abstract class AlertRequest(private val resources: Resources) {
|
||||
val show: MutableState<Boolean> = mutableStateOf(false)
|
||||
var title: String = ""
|
||||
var content: @Composable () -> Unit = {}
|
||||
var onOKAction: () -> Unit = {}
|
||||
var onCancelAction: () -> Unit = {}
|
||||
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
fun alert(title: String, content: String, onOk: () -> Unit, onCancel: () -> Unit = {}) {
|
||||
alert(title, { Text(text = content) }, onOk, onCancel)
|
||||
}
|
||||
|
||||
fun alert(
|
||||
@StringRes title: Int,
|
||||
@StringRes content: Int,
|
||||
onOk: () -> Unit,
|
||||
onCancel: () -> Unit = {}
|
||||
) {
|
||||
alert(resources.getString(title), resources.getString(content), onOk, onCancel)
|
||||
}
|
||||
|
||||
fun alert(
|
||||
@StringRes title: Int,
|
||||
content: @Composable () -> Unit,
|
||||
onOk: () -> Unit,
|
||||
onCancel: () -> Unit={}
|
||||
) {
|
||||
alert(resources.getString(title), content, onOk, onCancel)
|
||||
}
|
||||
}
|
||||
}
|
@ -33,7 +33,6 @@ class MessageReceiver : PushMessageReceiver() {
|
||||
|
||||
override fun onReceivePassThroughMessage(context: Context, message: MiPushMessage) {
|
||||
init(context)
|
||||
// Log.d("WH_", "onReceivePassThroughMessage: $message")
|
||||
mMessage = message.content
|
||||
if (!TextUtils.isEmpty(message.topic)) {
|
||||
mTopic = message.topic
|
||||
@ -46,7 +45,6 @@ class MessageReceiver : PushMessageReceiver() {
|
||||
|
||||
override fun onNotificationMessageClicked(context: Context, message: MiPushMessage) {
|
||||
init(context)
|
||||
// Log.d("WH_", "onNotificationMessageClicked: $message")
|
||||
mMessage = message.content
|
||||
if (!TextUtils.isEmpty(message.topic)) {
|
||||
mTopic = message.topic
|
||||
@ -59,7 +57,6 @@ class MessageReceiver : PushMessageReceiver() {
|
||||
|
||||
override fun onNotificationMessageArrived(context: Context, message: MiPushMessage) {
|
||||
init(context)
|
||||
// Log.d("WH_", "onNotificationMessageArrived: $message")
|
||||
mMessage = message.content
|
||||
if (!TextUtils.isEmpty(message.topic)) {
|
||||
mTopic = message.topic
|
||||
@ -72,7 +69,6 @@ class MessageReceiver : PushMessageReceiver() {
|
||||
|
||||
override fun onCommandResult(context: Context, message: MiPushCommandMessage) {
|
||||
init(context)
|
||||
// Log.d("WH_", "onCommandResult: $message")
|
||||
val command = message.command
|
||||
val arguments = message.commandArguments
|
||||
val cmdArg1 = if (arguments != null && arguments.size > 0) arguments[0] else null
|
||||
@ -108,7 +104,6 @@ class MessageReceiver : PushMessageReceiver() {
|
||||
|
||||
override fun onReceiveRegisterResult(context: Context, message: MiPushCommandMessage) {
|
||||
init(context)
|
||||
// Log.d("WH_", "onReceiveRegisterResult: $message")
|
||||
val command = message.command
|
||||
val arguments = message.commandArguments
|
||||
val cmdArg1 = if (arguments != null && arguments.size > 0) arguments[0] else null
|
||||
|
@ -1,19 +0,0 @@
|
||||
//package com.pushdeer.os.sss
|
||||
//
|
||||
//import android.content.Context
|
||||
//import android.content.Intent
|
||||
//import androidx.activity.result.contract.ActivityResultContract
|
||||
//import com.pushdeer.os.activity.QrScanActivity
|
||||
//
|
||||
//class MyActivityResultContract : ActivityResultContract<String, String>() {
|
||||
// override fun createIntent(context: Context, input: String): Intent {
|
||||
// return QrScanActivity.forScanResultIntent(context)
|
||||
// }
|
||||
//
|
||||
// override fun parseResult(resultCode: Int, intent: Intent?): String {
|
||||
// intent?.let {
|
||||
// return it.getStringExtra(QrScanActivity.DataKey).toString()
|
||||
// }
|
||||
// return ""
|
||||
// }
|
||||
//}
|
@ -7,13 +7,13 @@ class SettingStore(context:Context) {
|
||||
val store = Store.create(context,"setting")
|
||||
|
||||
var userToken by store.string("user-token","")
|
||||
var deviceName by store.string("device-name","My Dear Deer")
|
||||
var useRecv by store.boolean("use-recv",false) // 启用接收
|
||||
var useSend by store.boolean("use-send",false)
|
||||
var useSendNotification by store.boolean("use-send-notification",false)
|
||||
var notificationPackages by store.stringSet("notification-packages", emptySet())
|
||||
var useSendMissedCall by store.boolean("use-send=missed-call",false)
|
||||
var useSendSMS by store.boolean("use-send-sms",false)
|
||||
// var deviceName by store.string("device-name","My Dear Deer")
|
||||
// var useRecv by store.boolean("use-recv",false) // 启用接收
|
||||
// var useSend by store.boolean("use-send",false)
|
||||
// var useSendNotification by store.boolean("use-send-notification",false)
|
||||
// var notificationPackages by store.stringSet("notification-packages", emptySet())
|
||||
// var useSendMissedCall by store.boolean("use-send=missed-call",false)
|
||||
// var useSendSMS by store.boolean("use-send-sms",false)
|
||||
|
||||
var showMessageSender by store.boolean("show-message-sender",true)
|
||||
var thisPushSdk by store.string("this-push-sdk","mi-push")
|
||||
|
@ -1,8 +0,0 @@
|
||||
package com.pushdeer.os.typeExt
|
||||
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.launch
|
||||
|
@ -8,11 +8,12 @@ import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.DateRange
|
||||
import androidx.compose.runtime.Composable
|
||||
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.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
@ -24,8 +25,37 @@ import com.wh.common.util.TimeUtils
|
||||
|
||||
@ExperimentalMaterialApi
|
||||
@Composable
|
||||
fun KeyItem(key: PushKey, requestHolder: RequestHolder) {
|
||||
CardItemWithContent {
|
||||
fun KeyItem(key: PushKey,requestHolder: RequestHolder) {
|
||||
var name by remember {
|
||||
mutableStateOf(key.name)
|
||||
}
|
||||
CardItemWithContent(onClick = {
|
||||
requestHolder.alert.alert(
|
||||
title = R.string.main_key_alert_changekeyname,
|
||||
content = {
|
||||
Column {
|
||||
TextField(
|
||||
value = name,
|
||||
onValueChange = { name = it },
|
||||
shape = RoundedCornerShape(6.dp),
|
||||
singleLine = true,
|
||||
maxLines = 1,
|
||||
label = { Text(text = stringResource(id = R.string.main_key_alert_keyname)) },
|
||||
colors = TextFieldDefaults.textFieldColors(
|
||||
focusedIndicatorColor = Color.Transparent,
|
||||
unfocusedIndicatorColor = Color.Transparent,
|
||||
disabledIndicatorColor = Color.Transparent,
|
||||
errorIndicatorColor = Color.Transparent,
|
||||
)
|
||||
)
|
||||
}
|
||||
},
|
||||
onOk = {
|
||||
key.name = name
|
||||
requestHolder.keyRename(key)
|
||||
}
|
||||
)
|
||||
}) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
@ -113,7 +143,7 @@ fun KeyItem(key: PushKey, requestHolder: RequestHolder) {
|
||||
border = BorderStroke(1.dp, MaterialTheme.colors.MBlue),
|
||||
shape = RoundedCornerShape(6.dp)
|
||||
) {
|
||||
Text(text = "Reset")
|
||||
Text(text = stringResource(id = R.string.main_key_reset))
|
||||
}
|
||||
Button(
|
||||
onClick = {
|
||||
@ -125,7 +155,7 @@ fun KeyItem(key: PushKey, requestHolder: RequestHolder) {
|
||||
),
|
||||
shape = RoundedCornerShape(6.dp)
|
||||
) {
|
||||
Text(text = "Copy")
|
||||
Text(text = stringResource(id = R.string.main_key_copy))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,10 @@ import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.material.Card
|
||||
import androidx.compose.material.ExperimentalMaterialApi
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
@ -18,7 +21,6 @@ import androidx.compose.ui.viewinterop.AndroidView
|
||||
import com.pushdeer.os.R
|
||||
import com.pushdeer.os.data.database.entity.MessageEntity
|
||||
import com.pushdeer.os.holder.RequestHolder
|
||||
import com.pushdeer.os.ui.theme.MBlue
|
||||
import com.pushdeer.os.util.CurrentTimeUtil
|
||||
import com.pushdeer.os.values.ConstValues
|
||||
|
||||
@ -129,18 +131,18 @@ fun MarkdownMessageItem(message: MessageEntity, requestHolder: RequestHolder) {
|
||||
contentDescription = "",
|
||||
modifier = Modifier.size(40.dp)
|
||||
)
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_markdown),
|
||||
contentDescription = "",
|
||||
tint = MaterialTheme.colors.MBlue,
|
||||
modifier = Modifier
|
||||
.size(20.dp)
|
||||
.align(alignment = Alignment.BottomCenter)
|
||||
)
|
||||
// Icon(
|
||||
// painter = painterResource(id = R.drawable.ic_markdown),
|
||||
// contentDescription = "",
|
||||
// tint = MaterialTheme.colors.MBlue,
|
||||
// modifier = Modifier
|
||||
// .size(20.dp)
|
||||
// .align(alignment = Alignment.BottomCenter)
|
||||
// )
|
||||
}
|
||||
|
||||
Text(
|
||||
text = "${message.text}·${
|
||||
text = "${message.pushkey_name}·${
|
||||
CurrentTimeUtil.resolveUTCTimeAndNow(
|
||||
message.created_at,
|
||||
System.currentTimeMillis()
|
||||
@ -155,7 +157,7 @@ fun MarkdownMessageItem(message: MessageEntity, requestHolder: RequestHolder) {
|
||||
android.widget.TextView(ctx).apply {
|
||||
this.post {
|
||||
// requestHolder.markdown.configuration().theme().
|
||||
requestHolder.markdown.setMarkdown(this, message.desp)
|
||||
requestHolder.markdown.setMarkdown(this, message.text)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,38 @@
|
||||
package com.pushdeer.os.ui.compose.componment
|
||||
|
||||
import androidx.compose.material.AlertDialog
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import com.pushdeer.os.R
|
||||
import com.pushdeer.os.holder.RequestHolder
|
||||
|
||||
@Composable
|
||||
fun MyAlertDialog(alertRequest: RequestHolder.AlertRequest) {
|
||||
if (alertRequest.show.value) {
|
||||
AlertDialog(
|
||||
onDismissRequest = { alertRequest.show.value = false },
|
||||
confirmButton = {
|
||||
TextButton(onClick = {
|
||||
alertRequest.onOKAction.invoke()
|
||||
alertRequest.show.value = false
|
||||
}) {
|
||||
Text(text = stringResource(id = R.string.global_alert_ok))
|
||||
}
|
||||
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(onClick = {
|
||||
alertRequest.onCancelAction.invoke()
|
||||
alertRequest.show.value = false
|
||||
}) {
|
||||
Text(text = stringResource(id = R.string.global_alert_cancel))
|
||||
}
|
||||
|
||||
},
|
||||
title = { Text(text = alertRequest.title) },
|
||||
text = alertRequest.content
|
||||
)
|
||||
}
|
||||
}
|
@ -7,7 +7,6 @@ import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Delete
|
||||
import androidx.compose.material.icons.filled.Done
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
@ -20,13 +19,13 @@ import com.pushdeer.os.values.ConstValues
|
||||
@ExperimentalMaterialApi
|
||||
@Composable
|
||||
fun SwipeToDismissItem(
|
||||
onDismiss: () -> Unit,
|
||||
onAction: () -> Unit,
|
||||
sidePadding: Boolean = false,
|
||||
content: @Composable RowScope.() -> Unit
|
||||
) {
|
||||
val dismissState = rememberDismissState()
|
||||
if (dismissState.isDismissed(DismissDirection.EndToStart)) {
|
||||
onDismiss()
|
||||
onAction()
|
||||
}
|
||||
Column(modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
@ -34,7 +33,7 @@ fun SwipeToDismissItem(
|
||||
SwipeToDismiss(
|
||||
state = dismissState,
|
||||
background = {
|
||||
val direction = dismissState.dismissDirection ?: return@SwipeToDismiss
|
||||
// val direction = dismissState.dismissDirection ?: return@SwipeToDismiss
|
||||
|
||||
val color by animateColorAsState(
|
||||
when (dismissState.targetValue) {
|
||||
@ -44,15 +43,18 @@ fun SwipeToDismissItem(
|
||||
}
|
||||
)
|
||||
|
||||
val alignment = when (direction) {
|
||||
DismissDirection.StartToEnd -> Alignment.CenterStart
|
||||
DismissDirection.EndToStart -> Alignment.CenterEnd
|
||||
}
|
||||
// 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 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,
|
||||
@ -69,7 +71,7 @@ fun SwipeToDismissItem(
|
||||
)
|
||||
}
|
||||
},
|
||||
directions = setOf(DismissDirection.EndToStart, DismissDirection.EndToStart),
|
||||
directions = setOf(DismissDirection.EndToStart),
|
||||
dismissThresholds = { direction ->
|
||||
FractionalThreshold(if (direction == DismissDirection.EndToStart) 0.45f else 0.57f)
|
||||
},
|
||||
|
@ -25,7 +25,7 @@ import com.pushdeer.os.ui.compose.page.main.MainPageFrame
|
||||
|
||||
@ExperimentalMaterialApi
|
||||
@Composable
|
||||
fun LogDaoPage(requestHolder: RequestHolder) {
|
||||
fun LogDogPage(requestHolder: RequestHolder) {
|
||||
MainPageFrame(
|
||||
titleStringId = R.string.global_logdog,
|
||||
sideIcon = Icons.Default.Delete,
|
@ -1,76 +1,82 @@
|
||||
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.layout.Column
|
||||
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.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.pushdeer.os.ui.theme.MainBlue
|
||||
import com.pushdeer.os.ui.theme.MainGreen
|
||||
import com.willowtreeapps.signinwithapplebutton.SignInWithAppleConfiguration
|
||||
import com.willowtreeapps.signinwithapplebutton.SignInWithAppleResult
|
||||
import com.willowtreeapps.signinwithapplebutton.view.SignInWithAppleButton
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@ExperimentalMaterialApi
|
||||
@Composable
|
||||
fun LoginPage(requestHolder: RequestHolder) {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
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"
|
||||
)
|
||||
Card(
|
||||
onClick = { /*TODO*/ },
|
||||
shape = RoundedCornerShape(4.dp),
|
||||
contentDescription = "big push deer logo",
|
||||
modifier = Modifier
|
||||
.padding(bottom = 16.dp)
|
||||
.border(
|
||||
width = 1.dp,
|
||||
color = MainBlue,
|
||||
shape = RoundedCornerShape(4.dp)
|
||||
)
|
||||
) {
|
||||
Text(
|
||||
text = "Sign in with Apple",
|
||||
color = MainBlue,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier
|
||||
.padding(vertical = 16.dp)
|
||||
.fillMaxWidth(0.6F)
|
||||
|
||||
)
|
||||
}
|
||||
Card(
|
||||
onClick = {},
|
||||
shape = RoundedCornerShape(4.dp),
|
||||
modifier = Modifier.border(
|
||||
width = 1.dp,
|
||||
color = MainGreen,
|
||||
shape = RoundedCornerShape(4.dp)
|
||||
)
|
||||
) {
|
||||
Text(
|
||||
text = "Sign in with WeChat",
|
||||
color = MainGreen,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier
|
||||
.padding(vertical = 16.dp)
|
||||
.fillMaxWidth(0.6F)
|
||||
)
|
||||
}
|
||||
.clickable { requestHolder.globalNavController.navigate("logdog") }
|
||||
.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", {
|
||||
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")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
modifier = Modifier
|
||||
.align(alignment = Alignment.BottomCenter)
|
||||
.padding(bottom = 100.dp)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
@ -1,23 +1,25 @@
|
||||
package com.pushdeer.os.ui.compose.page.main
|
||||
|
||||
import android.os.Build
|
||||
import android.text.TextUtils
|
||||
import android.util.Log
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material.Card
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.ExperimentalMaterialApi
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.material.TextField
|
||||
import androidx.compose.material.TextFieldDefaults
|
||||
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.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pushdeer.os.R
|
||||
import com.pushdeer.os.data.api.data.request.DeviceInfo
|
||||
import com.pushdeer.os.data.api.data.response.UserInfo
|
||||
import com.pushdeer.os.holder.RequestHolder
|
||||
import com.pushdeer.os.ui.compose.componment.CardItemSingleLineWithIcon
|
||||
import com.pushdeer.os.ui.compose.componment.ListBottomBlankItem
|
||||
@ -32,78 +34,89 @@ fun DeviceListPage(requestHolder: RequestHolder) {
|
||||
MainPageFrame(
|
||||
titleStringId = Page.Devices.labelStringId,
|
||||
onSideIconClick = {
|
||||
requestHolder.deviceReg(
|
||||
deviceInfo = DeviceInfo().apply {
|
||||
name = System.currentTimeMillis().toString()
|
||||
device_id = "sdsdf"
|
||||
is_clip = 0
|
||||
}
|
||||
)
|
||||
}
|
||||
if (requestHolder.settingStore.thisDeviceId == "") {
|
||||
requestHolder.alert.alert(
|
||||
title = R.string.global_alert_title_confirm,
|
||||
content = R.string.alert_device_register_failed_push_sdk,
|
||||
onOk = {})
|
||||
// device regid got failed
|
||||
} else {
|
||||
requestHolder.deviceReg(
|
||||
deviceInfo = DeviceInfo().apply {
|
||||
name = SystemUtil.getDeviceModel()
|
||||
device_id = requestHolder.settingStore.thisDeviceId
|
||||
is_clip = 0
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
showSideIcon = requestHolder.pushDeerViewModel.shouldRegDevice()
|
||||
) {
|
||||
val state = rememberLazyListState()
|
||||
LazyColumn(state = state) {
|
||||
items(
|
||||
items = requestHolder.pushDeerViewModel.deviceList,
|
||||
key = { item: DeviceInfo -> item.id }) { deviceInfo: DeviceInfo ->
|
||||
SwipeToDismissItem(onDismiss = { requestHolder.deviceRemove(deviceInfo) }) {
|
||||
CardItemSingleLineWithIcon(
|
||||
onClick = {},
|
||||
resId = R.drawable.ipad_landscape2x,
|
||||
text = if (deviceInfo.device_id == requestHolder.settingStore.thisDeviceId) "${deviceInfo.name} (this device)" else deviceInfo.name
|
||||
)
|
||||
if (requestHolder.pushDeerViewModel.deviceList.isEmpty()) {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.main_device_list_placeholder)
|
||||
)
|
||||
}
|
||||
} else {
|
||||
val state = rememberLazyListState()
|
||||
LazyColumn(state = state) {
|
||||
items(
|
||||
items = requestHolder.pushDeerViewModel.deviceList,
|
||||
key = { item: DeviceInfo -> item.id }) { deviceInfo: DeviceInfo ->
|
||||
var name by remember {
|
||||
mutableStateOf(deviceInfo.name)
|
||||
}
|
||||
SwipeToDismissItem(
|
||||
onAction = { requestHolder.deviceRemove(deviceInfo) }
|
||||
) {
|
||||
CardItemSingleLineWithIcon(
|
||||
onClick = {
|
||||
requestHolder.alert.alert(
|
||||
title = R.string.main_device_alert_changedevicename,
|
||||
content = {
|
||||
Column {
|
||||
// Text(text = "type:${deviceInfo.type}")
|
||||
TextField(
|
||||
value = name,
|
||||
onValueChange = { name = it },
|
||||
shape = RoundedCornerShape(6.dp),
|
||||
singleLine = true,
|
||||
maxLines = 1,
|
||||
label = { Text(text = stringResource(id = R.string.main_device_alert_devicename)) },
|
||||
colors = TextFieldDefaults.textFieldColors(
|
||||
focusedIndicatorColor = Color.Transparent,
|
||||
unfocusedIndicatorColor = Color.Transparent,
|
||||
disabledIndicatorColor = Color.Transparent,
|
||||
errorIndicatorColor = Color.Transparent,
|
||||
)
|
||||
)
|
||||
}
|
||||
},
|
||||
onOk = {
|
||||
deviceInfo.name = name
|
||||
requestHolder.deviceRename(deviceInfo)
|
||||
}
|
||||
)
|
||||
},
|
||||
resId = R.drawable.ipad_landscape2x,
|
||||
text = if (deviceInfo.device_id == requestHolder.settingStore.thisDeviceId) "${deviceInfo.name} (${
|
||||
stringResource(
|
||||
id = R.string.main_device_this_device
|
||||
)
|
||||
}) " else deviceInfo.name
|
||||
)
|
||||
Log.d("WH_", "DeviceListPage: $deviceInfo")
|
||||
}
|
||||
}
|
||||
}
|
||||
item {
|
||||
ListBottomBlankItem()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ExperimentalMaterialApi
|
||||
@Composable
|
||||
fun DeviceListPage(userInfo: UserInfo, token: String, regid: String) {
|
||||
LazyColumn(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(horizontal = 8.dp)
|
||||
.padding(top = 8.dp)
|
||||
) {
|
||||
item {
|
||||
Card(elevation = 5.dp, onClick = {}, modifier = Modifier.fillMaxWidth()) {
|
||||
Column(modifier = Modifier.padding(horizontal = 16.dp, vertical = 14.dp)) {
|
||||
Text(text = "当前版本 Android ${SystemUtil.getSystemVersion()}")
|
||||
Text(text = "本机品牌 ${SystemUtil.getDeviceBrand()}")
|
||||
Text(text = "本机型号 ${SystemUtil.getDeviceModel()}")
|
||||
Text(text = "产品名称 ${Build.PRODUCT}")
|
||||
MiuiVersion()
|
||||
item {
|
||||
ListBottomBlankItem()
|
||||
}
|
||||
}
|
||||
}
|
||||
item {
|
||||
Card(elevation = 5.dp, onClick = {}, modifier = Modifier.fillMaxWidth()) {
|
||||
Column(modifier = Modifier.padding(horizontal = 16.dp, vertical = 14.dp)) {
|
||||
Text(text = "id ${userInfo.id}")
|
||||
Text(text = "name ${userInfo.name}")
|
||||
Text(text = "email ${userInfo.email}")
|
||||
Text(text = "app_id ${userInfo.app_id}")
|
||||
Text(text = "wechat_id ${userInfo.wechat_id}")
|
||||
Text(text = "created_at ${userInfo.created_at}")
|
||||
Text(text = "updated_at ${userInfo.updated_at}")
|
||||
Text(text = "level ${userInfo.level}")
|
||||
Text(text = "token $token")
|
||||
Text(text = "regid $regid")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun MiuiVersion() {
|
||||
val v = SystemUtil.getMiuiVersion()
|
||||
if (!TextUtils.isEmpty(v)) {
|
||||
Text(text = "Miui 版本 ${v}")
|
||||
}
|
||||
}
|
@ -1,11 +1,18 @@
|
||||
package com.pushdeer.os.ui.compose.page.main
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
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.res.stringResource
|
||||
import com.pushdeer.os.R
|
||||
import com.pushdeer.os.data.api.data.response.PushKey
|
||||
import com.pushdeer.os.holder.RequestHolder
|
||||
import com.pushdeer.os.ui.compose.componment.KeyItem
|
||||
@ -20,17 +27,29 @@ fun KeyListPage(requestHolder: RequestHolder) {
|
||||
titleStringId = Page.Keys.labelStringId,
|
||||
onSideIconClick = { requestHolder.keyGen() }
|
||||
) {
|
||||
LazyColumn(modifier = Modifier.fillMaxWidth()) {
|
||||
items(
|
||||
requestHolder.pushDeerViewModel.keyList,
|
||||
key = { item: PushKey -> item.id }) { pushKey: PushKey ->
|
||||
SwipeToDismissItem(onDismiss = { requestHolder.keyRemove(pushKey) }
|
||||
) {
|
||||
KeyItem(key = pushKey, requestHolder = requestHolder)
|
||||
}
|
||||
if(requestHolder.pushDeerViewModel.keyList.isEmpty()){
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.main_key_list_placeholder)
|
||||
)
|
||||
}
|
||||
item {
|
||||
ListBottomBlankItem()
|
||||
}else{
|
||||
LazyColumn(modifier = Modifier.fillMaxWidth()) {
|
||||
items(
|
||||
requestHolder.pushDeerViewModel.keyList,
|
||||
key = { item: PushKey -> item.id }) { pushKey: PushKey ->
|
||||
SwipeToDismissItem(onAction = { requestHolder.keyRemove(pushKey) }
|
||||
) {
|
||||
KeyItem(key = pushKey, requestHolder = requestHolder)
|
||||
}
|
||||
}
|
||||
item {
|
||||
ListBottomBlankItem()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,12 +26,22 @@ import com.pushdeer.os.holder.RequestHolder
|
||||
import com.pushdeer.os.ui.navigation.Page
|
||||
import com.pushdeer.os.ui.navigation.pageList
|
||||
import com.pushdeer.os.ui.theme.mainBottomBtn
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@ExperimentalAnimationApi
|
||||
@ExperimentalMaterialApi
|
||||
@Composable
|
||||
fun MainPage(requestHolder: RequestHolder) {
|
||||
|
||||
SideEffect {
|
||||
requestHolder.coroutineScope.launch {
|
||||
requestHolder.pushDeerViewModel.userInfo()
|
||||
requestHolder.pushDeerViewModel.keyList()
|
||||
requestHolder.pushDeerViewModel.deviceList()
|
||||
requestHolder.pushDeerViewModel.messageList()
|
||||
}
|
||||
}
|
||||
|
||||
var titleStringId by remember {
|
||||
mutableStateOf(Page.Devices.labelStringId)
|
||||
}
|
||||
|
@ -14,7 +14,9 @@ import androidx.compose.material.icons.filled.KeyboardArrowUp
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pushdeer.os.R
|
||||
import com.pushdeer.os.data.database.entity.MessageEntity
|
||||
import com.pushdeer.os.holder.RequestHolder
|
||||
import com.pushdeer.os.ui.compose.componment.*
|
||||
@ -78,7 +80,7 @@ fun MessageListPage(requestHolder: RequestHolder) {
|
||||
contentColor = Color.White
|
||||
),
|
||||
) {
|
||||
Text(text = "Send")
|
||||
Text(text = stringResource(id = R.string.main_message_send))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -87,15 +89,13 @@ fun MessageListPage(requestHolder: RequestHolder) {
|
||||
items = messageList,
|
||||
key = { item: MessageEntity -> item.id }) { message: MessageEntity ->
|
||||
SwipeToDismissItem(
|
||||
onDismiss = {
|
||||
onAction = {
|
||||
requestHolder.messageRemove(message.toMessage(), onDone = {
|
||||
requestHolder.messageViewModel.delete(message)
|
||||
})
|
||||
},
|
||||
// sidePadding = false
|
||||
sidePadding = message.type != "image"
|
||||
) {
|
||||
// ImageMessageItem(message)
|
||||
when (message.type) {
|
||||
"markdown" -> MarkdownMessageItem(message, requestHolder)
|
||||
"text" -> PlainTextMessageItem(message)
|
||||
|
@ -1,13 +1,12 @@
|
||||
package com.pushdeer.os.ui.compose.page.main
|
||||
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
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.res.stringResource
|
||||
import com.pushdeer.os.R
|
||||
import com.pushdeer.os.holder.RequestHolder
|
||||
import com.pushdeer.os.ui.compose.componment.SettingItem
|
||||
import com.pushdeer.os.ui.navigation.Page
|
||||
@ -24,8 +23,8 @@ fun SettingPage(requestHolder: RequestHolder) {
|
||||
) {
|
||||
item {
|
||||
SettingItem(
|
||||
text = "Hi ${requestHolder.pushDeerViewModel.userInfo.name} !",
|
||||
buttonString = "Logout"
|
||||
text = "${stringResource(id = R.string.main_setting_user_hi)} ${requestHolder.pushDeerViewModel.userInfo.name} !",
|
||||
buttonString = stringResource(id = R.string.main_setting_user_logout)
|
||||
) {
|
||||
requestHolder.settingStore.userToken = ""
|
||||
// logout 操作:
|
||||
@ -33,26 +32,26 @@ fun SettingPage(requestHolder: RequestHolder) {
|
||||
// 删除保存的 token
|
||||
}
|
||||
}
|
||||
item {
|
||||
SettingItem(
|
||||
text = "Customize Server",
|
||||
buttonString = "Scan QR"
|
||||
) {
|
||||
requestHolder.startQrScanActivity()
|
||||
}
|
||||
}
|
||||
item {
|
||||
SettingItem(
|
||||
text = "Do you like PushDeer ?",
|
||||
buttonString = "Like"
|
||||
) {
|
||||
}
|
||||
}
|
||||
// item {
|
||||
// SettingItem(
|
||||
// text = "Customize Server",
|
||||
// buttonString = "Scan QR"
|
||||
// ) {
|
||||
// requestHolder.startQrScanActivity()
|
||||
// }
|
||||
// }
|
||||
// item {
|
||||
// SettingItem(
|
||||
// text = "Do you like PushDeer ?",
|
||||
// buttonString = "Like"
|
||||
// ) {
|
||||
// }
|
||||
// }
|
||||
|
||||
item {
|
||||
SettingItem(
|
||||
text = "LogDog",
|
||||
buttonString = "Open"
|
||||
text = stringResource(id = R.string.main_setting_logdog),
|
||||
buttonString = stringResource(id = R.string.main_setting_logdog_open)
|
||||
) {
|
||||
requestHolder.globalNavController.navigate("logdog")
|
||||
}
|
||||
@ -61,12 +60,12 @@ fun SettingPage(requestHolder: RequestHolder) {
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun TogglePreferenceItem(label: String) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.fillMaxSize()
|
||||
) {
|
||||
Text(text = label)
|
||||
}
|
||||
}
|
||||
//@Composable
|
||||
//fun TogglePreferenceItem(label: String) {
|
||||
// Row(
|
||||
// verticalAlignment = Alignment.CenterVertically,
|
||||
// modifier = Modifier.fillMaxSize()
|
||||
// ) {
|
||||
// Text(text = label)
|
||||
// }
|
||||
//}
|
@ -19,7 +19,7 @@ import kotlinx.coroutines.withContext
|
||||
class PushDeerViewModel(
|
||||
private val settingStore: SettingStore,
|
||||
private val logDogRepository: LogDogRepository,
|
||||
private val pushDeerService:PushDeerApi,
|
||||
private val pushDeerService: PushDeerApi,
|
||||
private val messageRepository: MessageRepository
|
||||
) : ViewModel() {
|
||||
private val TAG = "WH_"
|
||||
@ -30,14 +30,18 @@ class PushDeerViewModel(
|
||||
val keyList = mutableStateListOf<PushKey>()
|
||||
// var messageList = mutableStateListOf<Message>()
|
||||
|
||||
suspend fun login(onReturn: (String) -> Unit = {}) {
|
||||
suspend fun login(idToken: String = "", onReturn: (String) -> Unit = {}) {
|
||||
withContext(Dispatchers.IO) {
|
||||
if (token == "") {
|
||||
if (token == "" && idToken != "") {
|
||||
try {
|
||||
pushDeerService.fakeLogin().let {
|
||||
pushDeerService.loginIdToken(idToken).let {
|
||||
it.content?.let { tokenOnly ->
|
||||
settingStore.userToken = tokenOnly.token
|
||||
token = tokenOnly.token
|
||||
Log.d(TAG, "login: $token")
|
||||
withContext(Dispatchers.Main) {
|
||||
onReturn.invoke(token)
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
@ -45,18 +49,26 @@ class PushDeerViewModel(
|
||||
logDogRepository.loge("login", "", e.toString())
|
||||
return@withContext
|
||||
}
|
||||
logDogRepository.logi("login","normally","nothing happened")
|
||||
logDogRepository.logi("login", "normally", "nothing happened")
|
||||
} else if (token == "" && idToken == "") {
|
||||
return@withContext
|
||||
} else if (token != "") {
|
||||
withContext(Dispatchers.Main) {
|
||||
onReturn.invoke(token)
|
||||
}
|
||||
}
|
||||
// Log.d(TAG, "login: token $token")
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun userInfo(onReturn: (UserInfo) -> Unit = {}) {
|
||||
suspend fun userInfo(onOk: (UserInfo) -> Unit = {}, onFailed: () -> Unit = {}) {
|
||||
withContext(Dispatchers.IO) {
|
||||
try {
|
||||
pushDeerService.userInfo(token).let {
|
||||
it.content?.let { ita ->
|
||||
userInfo = ita
|
||||
withContext(Dispatchers.Main) {
|
||||
onOk(userInfo)
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
@ -97,17 +109,17 @@ class PushDeerViewModel(
|
||||
pushDeerService.deviceList(token).let {
|
||||
it.content?.let {
|
||||
deviceList.clear()
|
||||
deviceList.addAll(it.devices)
|
||||
deviceList.addAll(it.devices.reversed())
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.d(TAG, "deviceList: ${e.localizedMessage}")
|
||||
logDogRepository.loge("deviceList", "", e.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun shouldRegDevice(): Boolean {
|
||||
// Log.d(TAG, "isDeviceReged: current device id ${settingStore.thisDeviceId}")
|
||||
return deviceList.none { it.device_id == settingStore.thisDeviceId }
|
||||
}
|
||||
|
||||
@ -120,6 +132,19 @@ class PushDeerViewModel(
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.d(TAG, "deviceRemove: ${e.localizedMessage}")
|
||||
logDogRepository.loge("deviceRemove", "", e.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun deviceRename(deviceInfo: DeviceInfo,onReturn: () -> Unit={}){
|
||||
withContext(Dispatchers.IO){
|
||||
try {
|
||||
pushDeerService.deviceRename(token,deviceInfo.id,deviceInfo.name)
|
||||
onReturn()
|
||||
}catch (e:Exception){
|
||||
Log.d(TAG, "deviceRename: ${e.localizedMessage}")
|
||||
logDogRepository.loge("deviceRename", "", e.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -135,6 +160,7 @@ class PushDeerViewModel(
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.d(TAG, "keyGen: ${e.localizedMessage}")
|
||||
logDogRepository.loge("keyGen", "", e.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -152,6 +178,23 @@ class PushDeerViewModel(
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.d(TAG, "keyRegen: ${e.localizedMessage}")
|
||||
logDogRepository.loge("keyRegen", "", e.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun keyRename(key: PushKey,onReturn: () -> Unit={}){
|
||||
withContext(Dispatchers.IO){
|
||||
try {
|
||||
pushDeerService.keyRename(
|
||||
token,
|
||||
key.id,
|
||||
key.name
|
||||
)
|
||||
onReturn()
|
||||
}catch (e: Exception) {
|
||||
Log.d(TAG, "keyRename: ${e.localizedMessage}")
|
||||
logDogRepository.loge("keyRename", "", e.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -167,6 +210,7 @@ class PushDeerViewModel(
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.d(TAG, "keyList: ${e.localizedMessage}")
|
||||
logDogRepository.loge("keyList", "", e.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -179,6 +223,7 @@ class PushDeerViewModel(
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.d(TAG, "keyRemove: ${e.localizedMessage}")
|
||||
logDogRepository.loge("keyRemove", "", e.toString())
|
||||
}
|
||||
}
|
||||
|
||||
|
4
android/app/src/main/res/values-zh-rCN/strings.xml
Normal file
4
android/app/src/main/res/values-zh-rCN/strings.xml
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">PushDeer</string>
|
||||
</resources>
|
29
android/app/src/main/res/values-zh/strings.xml
Normal file
29
android/app/src/main/res/values-zh/strings.xml
Normal file
@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">PushDeer</string>
|
||||
<string name="main_device">设备</string>
|
||||
<string name="main_key">密钥</string>
|
||||
<string name="main_message">消息</string>
|
||||
<string name="main_setting">设置</string>
|
||||
<string name="global_logdog">LogDog-罗格狗</string>
|
||||
<string name="main_key_reset">重置</string>
|
||||
<string name="main_key_copy">复制</string>
|
||||
<string name="main_setting_logdog_open">打开</string>
|
||||
<string name="main_setting_user_hi">你好</string>
|
||||
<string name="main_setting_user_logout">注销</string>
|
||||
<string name="main_setting_logdog">LogDog-罗格狗</string>
|
||||
<string name="main_device_list_placeholder">点击\"+\"创建新设备</string>
|
||||
<string name="main_device_this_device">本设备</string>
|
||||
<string name="global_alert_title_confirm">确认</string>
|
||||
<string name="alert_device_register_failed_push_sdk">本设备在厂商推送服务注册失败</string>
|
||||
<string name="main_message_send">发送</string>
|
||||
<string name="global_alert_title_alert">警告</string>
|
||||
<string name="main_message_send_alert">发送消息前请创建新的密钥</string>
|
||||
<string name="global_alert_ok">确认</string>
|
||||
<string name="global_alert_cancel">取消</string>
|
||||
<string name="main_key_list_placeholder">点击\"+\"创建新密钥</string>
|
||||
<string name="main_device_alert_changedevicename">修改设备名称</string>
|
||||
<string name="main_device_alert_devicename">设备名称</string>
|
||||
<string name="main_key_alert_changekeyname">修改密钥名称</string>
|
||||
<string name="main_key_alert_keyname">密钥名称</string>
|
||||
</resources>
|
@ -5,4 +5,24 @@
|
||||
<string name="main_message">Message</string>
|
||||
<string name="main_setting">Setting</string>
|
||||
<string name="global_logdog">LogDog</string>
|
||||
<string name="main_key_reset">Reset</string>
|
||||
<string name="main_key_copy">Copy</string>
|
||||
<string name="main_setting_logdog_open">Open</string>
|
||||
<string name="main_setting_user_hi">Hi</string>
|
||||
<string name="main_setting_user_logout">Logout</string>
|
||||
<string name="main_setting_logdog">LogDog</string>
|
||||
<string name="main_device_list_placeholder">It\'s Empty, Click \'+\' to Add New Device.</string>
|
||||
<string name="main_device_this_device">this device</string>
|
||||
<string name="global_alert_title_confirm">Confirm</string>
|
||||
<string name="alert_device_register_failed_push_sdk">This Device Registered Failed in PushSDK</string>
|
||||
<string name="main_message_send">Send</string>
|
||||
<string name="global_alert_title_alert">Alert</string>
|
||||
<string name="main_message_send_alert">You Should Add One PushKey</string>
|
||||
<string name="global_alert_ok">OK</string>
|
||||
<string name="global_alert_cancel">Cancel</string>
|
||||
<string name="main_key_list_placeholder">It\'s Empty, Click \'+\' to Add New Key.</string>
|
||||
<string name="main_device_alert_changedevicename">Change Device Name</string>
|
||||
<string name="main_device_alert_devicename">name</string>
|
||||
<string name="main_key_alert_changekeyname">Change Key Name</string>
|
||||
<string name="main_key_alert_keyname">name</string>
|
||||
</resources>
|
||||
|
@ -6,6 +6,7 @@ buildscript {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
maven { url 'https://jitpack.io' }
|
||||
}
|
||||
dependencies {
|
||||
classpath "com.android.tools.build:gradle:7.0.4"
|
||||
|
@ -3,6 +3,7 @@ dependencyResolutionManagement {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
maven { url 'https://jitpack.io' }
|
||||
// maven { url 'https://developer.huawei.com/repo/' }
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user