mirror of
https://github.com/easychen/pushdeer.git
synced 2025-01-08 22:15:57 +08:00
commit
330554a55b
@ -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,14 @@
|
||||
* 调整项目文件结构
|
||||
* 将数据库用作message列表的直接数据来源
|
||||
|
||||
* 2022-01-20
|
||||
* 修改 /device/reg post参数增加 type=android
|
||||
* 集成 SignIn With Apple
|
||||
* 调整设备列表加号的显示和操作逻辑
|
||||
* 将自动注册设备修改为手动点击加号注册设备
|
||||
* 当前app几乎处于可以使用的状态
|
||||
|
||||
|
||||
### 感谢
|
||||
|
||||
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'
|
||||
}
|
@ -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,7 @@ 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 coilImageLoader: ImageLoader by lazy {
|
||||
ImageLoader.Builder(this)
|
||||
@ -69,6 +72,7 @@ class MainActivity : ComponentActivity(), RequestHolder {
|
||||
}
|
||||
.build()
|
||||
}
|
||||
override val alert: RequestHolder.AlertRequest = object : RequestHolder.AlertRequest() {}
|
||||
|
||||
override val markdown: Markwon by lazy {
|
||||
Markwon.builder(this)
|
||||
@ -106,40 +110,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 +141,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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,14 @@ import com.pushdeer.os.data.api.data.response.*
|
||||
import retrofit2.http.*
|
||||
|
||||
interface PushDeerApi {
|
||||
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>
|
||||
|
||||
@ -21,7 +29,7 @@ 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("/key/gen")
|
||||
@ -49,5 +57,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"
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,11 @@ import android.content.Intent
|
||||
import android.util.Log
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
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.activity.QrScanActivity
|
||||
@ -26,7 +31,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 +40,10 @@ interface RequestHolder {
|
||||
val activityOpener: ActivityResultLauncher<Intent>
|
||||
val coilImageLoader: ImageLoader
|
||||
|
||||
val fragmentManager:FragmentManager
|
||||
|
||||
val alert: AlertRequest
|
||||
|
||||
val clipboardManager: ClipboardManager
|
||||
|
||||
fun copyPlainString(str: String) {
|
||||
@ -64,7 +73,7 @@ interface RequestHolder {
|
||||
}
|
||||
}
|
||||
|
||||
fun deviceReg(deviceInfo: DeviceInfo){
|
||||
fun deviceReg(deviceInfo: DeviceInfo) {
|
||||
coroutineScope.launch {
|
||||
pushDeerViewModel.deviceReg(deviceInfo)
|
||||
}
|
||||
@ -83,18 +92,20 @@ interface RequestHolder {
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
} else {
|
||||
alert.alert("Alert", "You Should Add One PushKey", onOk = {})
|
||||
Log.d("WH_", "messagePushTest: keylist is empty")
|
||||
}
|
||||
}
|
||||
|
||||
fun messageRemove(message: Message,onDone:()->Unit={}) {
|
||||
fun messageRemove(message: Message, onDone: () -> Unit = {}) {
|
||||
coroutineScope.launch {
|
||||
// pushDeerViewModel.messageList.remove(message)
|
||||
pushDeerViewModel.messageRemove(message.id)
|
||||
@ -112,4 +123,33 @@ interface RequestHolder {
|
||||
logDogViewModel.clear()
|
||||
}
|
||||
}
|
||||
|
||||
abstract class AlertRequest {
|
||||
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 = {}) {
|
||||
this.title = title
|
||||
this.content = { Text(text = content) }
|
||||
this.onOKAction = onOk
|
||||
this.onCancelAction = onCancel
|
||||
this.show.value = true
|
||||
}
|
||||
}
|
||||
}
|
@ -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,36 @@
|
||||
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 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 = "Ok")
|
||||
}
|
||||
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(onClick = {
|
||||
alertRequest.onCancelAction.invoke()
|
||||
alertRequest.show.value = false
|
||||
}) {
|
||||
Text(text = "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,7 +1,9 @@
|
||||
package com.pushdeer.os.ui.compose.page
|
||||
|
||||
import android.util.Log
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
@ -16,24 +18,86 @@ 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
|
||||
) {
|
||||
|
||||
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"
|
||||
contentDescription = "big push deer logo",
|
||||
modifier = Modifier.clickable {
|
||||
requestHolder.globalNavController.navigate("logdog")
|
||||
}
|
||||
)
|
||||
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
|
||||
.padding(bottom = 16.dp)
|
||||
.border(
|
||||
width = 1.dp,
|
||||
color = MainBlue,
|
||||
shape = RoundedCornerShape(4.dp)
|
||||
)
|
||||
)
|
||||
Card(
|
||||
onClick = { /*TODO*/ },
|
||||
onClick = {
|
||||
|
||||
},
|
||||
shape = RoundedCornerShape(4.dp),
|
||||
modifier = Modifier
|
||||
.padding(bottom = 16.dp)
|
||||
|
@ -1,23 +1,18 @@
|
||||
package com.pushdeer.os.ui.compose.page.main
|
||||
|
||||
import android.os.Build
|
||||
import android.text.TextUtils
|
||||
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.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.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 +27,54 @@ 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 = "Confirm",
|
||||
content = "This Device Registered Failed in PushSDK",
|
||||
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 = "It's Empty, Click '+' to Add New Device"
|
||||
)
|
||||
}
|
||||
} else {
|
||||
val state = rememberLazyListState()
|
||||
LazyColumn(state = state) {
|
||||
items(
|
||||
items = requestHolder.pushDeerViewModel.deviceList,
|
||||
key = { item: DeviceInfo -> item.id }) { deviceInfo: DeviceInfo ->
|
||||
SwipeToDismissItem(
|
||||
onAction = { 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
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
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,10 +1,15 @@
|
||||
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 com.pushdeer.os.data.api.data.response.PushKey
|
||||
import com.pushdeer.os.holder.RequestHolder
|
||||
@ -20,17 +25,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 = "It's Empty, Click '+' to Add New Key"
|
||||
)
|
||||
}
|
||||
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)
|
||||
}
|
||||
|
@ -87,15 +87,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)
|
||||
|
@ -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) {
|
||||
@ -107,7 +119,6 @@ class PushDeerViewModel(
|
||||
}
|
||||
|
||||
fun shouldRegDevice(): Boolean {
|
||||
// Log.d(TAG, "isDeviceReged: current device id ${settingStore.thisDeviceId}")
|
||||
return deviceList.none { it.device_id == settingStore.thisDeviceId }
|
||||
}
|
||||
|
||||
|
@ -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