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