Merge branch 'main' of https://github.com/easychen/pushdeer into main

This commit is contained in:
EasyChen 2022-01-21 13:05:49 +08:00
commit 93024fd028
35 changed files with 629 additions and 318 deletions

View File

@ -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>

View File

@ -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

View File

@ -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'
}

View 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"
}

Binary file not shown.

View File

@ -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 {

View File

@ -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)
}
}
}

View File

@ -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
}

View File

@ -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"
)
}

View File

@ -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
)
}
}

View File

@ -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
}
}

View File

@ -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;
}
}

View File

@ -1,4 +0,0 @@
package com.pushdeer.os.holder
interface DataHolder {
}

View File

@ -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)
}
}
}

View File

@ -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

View File

@ -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 ""
// }
//}

View File

@ -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")

View File

@ -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

View File

@ -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))
}
}
}

View File

@ -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)
}
}

View File

@ -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
)
}
}

View File

@ -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)
},

View File

@ -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,

View File

@ -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)
)
}
}

View File

@ -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}")
}
}

View File

@ -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()
}
}
}
}

View File

@ -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)
}

View File

@ -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)

View File

@ -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)
// }
//}

View File

@ -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())
}
}

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">PushDeer</string>
</resources>

View 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>

View File

@ -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>

View File

@ -6,6 +6,7 @@ buildscript {
repositories {
google()
mavenCentral()
maven { url 'https://jitpack.io' }
}
dependencies {
classpath "com.android.tools.build:gradle:7.0.4"

View File

@ -3,6 +3,7 @@ dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven { url 'https://jitpack.io' }
// maven { url 'https://developer.huawei.com/repo/' }
}
}