diff --git a/app/build.gradle.kts b/app/build.gradle.kts index a700513..36a211b 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -13,12 +13,18 @@ android { minSdk = 24 targetSdk = 34 versionCode = 1 - versionName = "0.4.5.6-beta" + versionName = "0.4.6.0-beta" // 使 DialogX 的实时模糊效果生效 renderscriptTargetApi = 21 renderscriptSupportModeEnabled = true + ndk { + abiFilters.add("armeabi") + abiFilters.add("armeabi-v7a") + abiFilters.add("arm64-v8a") + } + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { useSupportLibrary = true @@ -150,9 +156,6 @@ dependencies { //文件选择对话框 implementation("com.github.kongzue.DialogXSample:FileDialog:$dialogx_sample_version") - // PermissionX - implementation("com.guolindev.permissionx:permissionx:1.7.1") - // Cascade 下拉菜单 val cascade_version = "2.3.0" implementation("me.saket.cascade:cascade-compose:$cascade_version") @@ -190,4 +193,14 @@ dependencies { val net_version = "3.6.4" implementation("com.github.liangjingkanji:Net:$net_version") + // 权限请求框架:https://github.com/getActivity/XXPermissions + val xxpermission_version = "18.63" + implementation ("com.github.getActivity:XXPermissions:$xxpermission_version") + + // 百度地图 SDK + // 地图组件 +// implementation ("com.baidu.lbsyun:BaiduMapSDK_Map:7.6.1") + // 基础定位组件 + implementation ("com.baidu.lbsyun:BaiduMapSDK_Location:9.3.7") + } \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 481bb43..575c9a0 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -18,4 +18,6 @@ # If you keep the line number information, uncomment this to # hide the original source file name. -#-renamesourcefileattribute SourceFile \ No newline at end of file +#-renamesourcefileattribute SourceFile + +-keep class com.baidu.location.** {*;} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 945a730..ec81fc2 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,13 +2,26 @@ - - - - - + + + + + + + + + + + + + + + + + + + + + + + @@ -39,6 +56,7 @@ android:name=".CommonActivity" android:exported="false" android:label="@string/title_activity_common" + android:screenOrientation="portrait" android:theme="@style/Theme.EasyNoteDemo" android:windowSoftInputMode="adjustResize"> @@ -51,6 +69,7 @@ android:name=".EventActivity" android:exported="false" android:label="@string/title_activity_event" + android:screenOrientation="portrait" android:theme="@style/Theme.EasyNoteDemo" android:windowSoftInputMode="adjustResize"> @@ -63,6 +82,7 @@ android:name=".AppInfoActivity" android:exported="false" android:label="@string/title_activity_app_info" + android:screenOrientation="portrait" android:theme="@style/Theme.EasyNoteDemo" android:windowSoftInputMode="adjustNothing"> @@ -75,6 +95,7 @@ android:name=".EditActivity" android:exported="false" android:label="@string/title_activity_edit" + android:screenOrientation="portrait" android:theme="@style/Theme.EasyNoteDemo"> @@ -86,6 +107,7 @@ android:name=".SettingActivity" android:exported="false" android:label="@string/title_activity_setting" + android:screenOrientation="portrait" android:theme="@style/Theme.EasyNoteDemo"> @@ -97,6 +119,7 @@ android:name=".MainActivity" android:exported="true" android:label="@string/app_name" + android:screenOrientation="portrait" android:theme="@style/Theme.EasyNoteDemo" android:windowSoftInputMode="adjustResize"> diff --git a/app/src/main/java/com/oxyethylene/easynote/BackupSettingActivity.kt b/app/src/main/java/com/oxyethylene/easynote/BackupSettingActivity.kt index 3c48aa0..c6a43f5 100644 --- a/app/src/main/java/com/oxyethylene/easynote/BackupSettingActivity.kt +++ b/app/src/main/java/com/oxyethylene/easynote/BackupSettingActivity.kt @@ -45,7 +45,7 @@ class BackupSettingActivity : ComponentActivity() { val backupSettingList = listOf( DialogSetting( - SettingName = "修改备份/导出文件夹" + settingName = "修改备份/导出文件夹" ) { MessageDialog.build(MIUIStyle()) .setTitle("修改备份文件夹") @@ -63,7 +63,7 @@ class BackupSettingActivity : ComponentActivity() { .show() }, DialogSetting( - SettingName = "恢复默认导出文件夹", + settingName = "恢复默认导出文件夹", warning = "原备份文件夹下的文件将会保留,需要自行删除" ) { MessageDialog.build(MIUIStyle()) @@ -81,13 +81,13 @@ class BackupSettingActivity : ComponentActivity() { .show() }, DialogSetting( - SettingName = "手动备份", + settingName = "手动备份", description = "将所有文章备份到指定的文件夹" ) { DebugInfoDial.todoDialog("手动备份") }, DialogSetting( - SettingName = "从本地恢复文章备份", + settingName = "从本地恢复文章备份", description = "将所有文章备份到指定的文件夹" ) { DebugInfoDial.todoDialog("从本地恢复文章备份") diff --git a/app/src/main/java/com/oxyethylene/easynote/CommonActivity.kt b/app/src/main/java/com/oxyethylene/easynote/CommonActivity.kt index 601ff2f..4654250 100644 --- a/app/src/main/java/com/oxyethylene/easynote/CommonActivity.kt +++ b/app/src/main/java/com/oxyethylene/easynote/CommonActivity.kt @@ -6,6 +6,7 @@ import androidx.activity.compose.setContent import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.Surface import androidx.compose.ui.Modifier +import com.kongzue.dialogx.DialogX import com.oxyethylene.easynote.ui.commonactivity.EditorSettingPageUI import com.oxyethylene.easynote.ui.commonactivity.KeywordPageUI import com.oxyethylene.easynote.ui.commonactivity.LabSettingPageUI @@ -29,6 +30,8 @@ class CommonActivity : ComponentActivity() { val UITitle = intent.getStringExtra("title") ?: "" + DialogX.init(applicationContext) + setContent { EasyNoteTheme { Surface( diff --git a/app/src/main/java/com/oxyethylene/easynote/EditActivity.kt b/app/src/main/java/com/oxyethylene/easynote/EditActivity.kt index 62de6f7..7be2cb5 100644 --- a/app/src/main/java/com/oxyethylene/easynote/EditActivity.kt +++ b/app/src/main/java/com/oxyethylene/easynote/EditActivity.kt @@ -29,6 +29,11 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.unit.dp import androidx.compose.ui.viewinterop.AndroidView +import com.baidu.location.BDAbstractLocationListener +import com.baidu.location.BDLocation +import com.baidu.location.LocationClient +import com.baidu.location.LocationClientOption +import com.drake.net.utils.TipUtils import com.kongzue.albumdialog.PhotoAlbumDialog import com.kongzue.albumdialog.util.SelectPhotoCallback import com.kongzue.filedialog.FileDialog @@ -43,9 +48,11 @@ import com.oxyethylene.easynote.ui.editactivity.EditActionBarButton import com.oxyethylene.easynote.ui.editactivity.EditActionBarHelper import com.oxyethylene.easynote.ui.editactivity.EditActionBarMenu import com.oxyethylene.easynote.ui.editactivity.KeywordUtilButton +import com.oxyethylene.easynote.ui.editactivity.LocationInfoButton import com.oxyethylene.easynote.ui.editactivity.TitleLine import com.oxyethylene.easynote.ui.theme.BackGround import com.oxyethylene.easynote.ui.theme.EasyNoteTheme +import com.oxyethylene.easynote.util.DateUtil import com.oxyethylene.easynote.util.FileUtil import com.oxyethylene.easynote.util.KeywordUtil import com.oxyethylene.easynote.util.NoteUtil @@ -55,18 +62,62 @@ import java.io.File class EditActivity : ComponentActivity() { - // 富文本编辑器 + /** + * 富文本编辑器 + */ private lateinit var richEditor: RichEditor - // 编辑器纯文本内容 + /** + * 编辑器纯文本内容 + */ private var plainText = "" - // 获取当前编辑的文章 + /** + * 文本是否被修改过 + */ + private var modified = false + + /** + * 当前编辑的文章 + */ private val note = FileUtil.getNote(NoteUtil.getNoteId()) + /** + * 百度地图 SDK 请求客户端 + */ + private var mLocationClient: LocationClient? = null + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + try { + mLocationClient = LocationClient(applicationContext) + } catch (ex : Exception) { + TipUtils.toast(ex.message) + } + + val option = LocationClientOption().apply { + setIsNeedAddress(true) + } + + mLocationClient?.locOption = option + + mLocationClient?.registerLocationListener( + object : BDAbstractLocationListener() { + override fun onReceiveLocation(location: BDLocation?) { + val updateTime = DateUtil.getCurrentDateTime() + + val address = location?.addrStr ?: SettingUtil.defaultLocation + + // 更新修改地点 + NoteUtil.updateRecord(address, updateTime) + + FileUtil.setNoteUpdateTime(NoteUtil.getNoteId(), updateTime) + mLocationClient!!.stop() + } + } + ) + setContent { EasyNoteTheme { @@ -91,6 +142,9 @@ class EditActivity : ComponentActivity() { onKeywordUpdate = { keywordMap = KeywordUtil.getBindedKeywords(note!!.keywordList) } ) { plainText } } + if (SettingUtil.enableLocation) { + LocationInfoButton(Modifier.align(Alignment.CenterVertically).padding(start = 20.dp)) + } KeywordUtilButton(NoteUtil.getNoteId()) { keywordMap = KeywordUtil.getBindedKeywords(note!!.keywordList) } @@ -121,22 +175,18 @@ class EditActivity : ComponentActivity() { } // 字体加粗 EditActionBarButton(R.mipmap.ic_set_bold) { -// richEditor.focusEditor() richEditor.setBold() } // 字体倾斜 EditActionBarButton(R.mipmap.ic_set_italic) { -// richEditor.focusEditor() richEditor.setItalic() } // 添加下划线 EditActionBarButton(R.mipmap.ic_set_underline) { -// richEditor.focusEditor() richEditor.setUnderline() } // 添加删除线 EditActionBarButton(R.mipmap.ic_set_strike_through) { -// richEditor.focusEditor() richEditor.setStrikeThrough() } // 文本对齐方式 @@ -159,7 +209,6 @@ class EditActivity : ComponentActivity() { } // 插入图片 EditActionBarButton(R.mipmap.ic_insert_photo) { -// richEditor.focusEditor() PhotoAlbumDialog.build() .setMaxSelectPhotoCount(1) .setCompressQuality(80) @@ -181,7 +230,6 @@ class EditActivity : ComponentActivity() { } // 插入视频 EditActionBarButton(R.mipmap.ic_insert_video) { -// richEditor.focusEditor() FileDialog.build() .setShowFileDate(true) .setSuffixArray(arrayOf(".mp4")) @@ -196,7 +244,6 @@ class EditActivity : ComponentActivity() { } // 插入音频 EditActionBarButton(R.mipmap.ic_insert_audio) { -// richEditor.focusEditor() FileDialog.build() .setShowFileDate(true) .setSuffixArray(arrayOf(".ogg", ".mp3", ".flac")) @@ -227,7 +274,12 @@ class EditActivity : ComponentActivity() { richEditor = findViewById(R.id.editor) richEditor.setBackgroundColor(Color.Transparent.toArgb()) richEditor.settings.allowFileAccess = true - richEditor.setOnTextChangeListener { plainText = richEditor.plainText } + richEditor.setOnTextChangeListener { + // 更新纯文本内容 + plainText = richEditor.plainText + // 更新修改标记 + modified = true + } // 加载已有内容 richEditor.html = NoteUtil.loadFile(this@EditActivity) // 初始化纯文本内容 @@ -257,7 +309,9 @@ class EditActivity : ComponentActivity() { super.onDestroy() richEditor.html?.let { NoteUtil.saveFile(this, it) } richEditor.pauseMediaPlayers() - FileUtil.setNoteUpdateTime(NoteUtil.getNoteId()) + if (modified && SettingUtil.enableLocation) { + mLocationClient?.start() + } } override fun onStop() { diff --git a/app/src/main/java/com/oxyethylene/easynote/MainActivity.kt b/app/src/main/java/com/oxyethylene/easynote/MainActivity.kt index f552beb..f3479fd 100644 --- a/app/src/main/java/com/oxyethylene/easynote/MainActivity.kt +++ b/app/src/main/java/com/oxyethylene/easynote/MainActivity.kt @@ -1,6 +1,8 @@ package com.oxyethylene.easynote import android.annotation.SuppressLint +import android.content.Context +import android.os.Build import android.os.Bundle import android.os.Handler import android.os.Looper @@ -24,8 +26,12 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.lifecycle.ViewModelProvider +import com.baidu.location.LocationClient import com.drake.net.NetConfig import com.drake.net.okhttp.setErrorHandler +import com.hjq.permissions.OnPermissionCallback +import com.hjq.permissions.Permission +import com.hjq.permissions.XXPermissions import com.kongzue.dialogx.DialogX import com.kongzue.dialogx.dialogs.PopNotification import com.kongzue.dialogx.style.MIUIStyle @@ -41,6 +47,7 @@ import com.oxyethylene.easynote.errorhandler.GPTErrorHandler import com.oxyethylene.easynote.ui.mainactivity.EventPageArea import com.oxyethylene.easynote.ui.mainactivity.FolderMenuArea import com.oxyethylene.easynote.ui.mainactivity.TopMenuBar +import com.oxyethylene.easynote.ui.mainactivity.callPermissionCheck import com.oxyethylene.easynote.ui.theme.BackGround import com.oxyethylene.easynote.ui.theme.EasyNoteTheme import com.oxyethylene.easynote.util.EventUtil.initEventList @@ -52,9 +59,11 @@ import com.oxyethylene.easynote.util.FileUtil.initFileUtil import com.oxyethylene.easynote.util.FileUtil.updateDirectory import com.oxyethylene.easynote.util.GPTUtil import com.oxyethylene.easynote.util.NlpUtil +import com.oxyethylene.easynote.util.NoteUtil.initNoteUtil import com.oxyethylene.easynote.viewmodel.MainViewModel import com.oxyethylene.easynote.viewmodel.factory.MainViewModelFactory import kotlinx.coroutines.launch +import java.util.Properties class MainActivity : ComponentActivity() { @@ -63,7 +72,7 @@ class MainActivity : ComponentActivity() { lateinit var database: AppDatabase - val handler = object : Handler(Looper.getMainLooper()) { + private val handler = object : Handler(Looper.getMainLooper()) { override fun handleMessage(msg: Message) { // 在这里可以进行UI操作 when (msg.what) { @@ -93,10 +102,20 @@ class MainActivity : ComponentActivity() { database = AppDatabase.getDatabase(this) + checkPermission(this) + // 初始化工具类 initFileUtil(viewModel, database, handler) + initNoteUtil(database) initEventUtil(viewModel, database, handler) + // 初始化定位工具 + val prop = Properties(); + prop.load(applicationContext.assets.open("auth.properties")) + LocationClient.setKey(prop.getProperty("BD_MAP_SDK")) + LocationClient.setAgreePrivacy(true) + + // 初始化默认备份目录 FileUtil.initDefaultBackupDir() @@ -116,7 +135,7 @@ class MainActivity : ComponentActivity() { initEventList() // 初始化 DialogX - DialogX.init(this) + DialogX.init(applicationContext) DialogX.autoShowInputKeyboard = false DialogX.cancelableTipDialog = false @@ -189,5 +208,41 @@ class MainActivity : ComponentActivity() { } + override fun onRestart() { + super.onRestart() + checkPermission(this) + } + + fun checkPermission (context: Context) { + + val requestList= ArrayList().apply { + add(Permission.ACCESS_FINE_LOCATION) + add(Permission.ACCESS_COARSE_LOCATION) + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S_V2) { + add(Permission.MANAGE_EXTERNAL_STORAGE) + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + add(Permission.READ_MEDIA_AUDIO) + add(Permission.READ_MEDIA_VIDEO) + add(Permission.READ_MEDIA_IMAGES) + } + } + + XXPermissions.with(context) + .permission(requestList) + .request( + object : OnPermissionCallback { + override fun onGranted(permissions: MutableList, allGranted: Boolean) { + + } + + override fun onDenied(permissions: MutableList, doNotAskAgain: Boolean) { + callPermissionCheck(context, true) + } + } + ) + + } + } diff --git a/app/src/main/java/com/oxyethylene/easynote/common/constant/ConfigConstants.kt b/app/src/main/java/com/oxyethylene/easynote/common/constant/ConfigConstants.kt index 71d5406..186b771 100644 --- a/app/src/main/java/com/oxyethylene/easynote/common/constant/ConfigConstants.kt +++ b/app/src/main/java/com/oxyethylene/easynote/common/constant/ConfigConstants.kt @@ -21,11 +21,6 @@ const val EASYNOTE_BACKUP_FOLDER = "Documents/EasyNote" */ const val FONT_FAMILY_DEFAULT = "default" -/** - * 第三方字体-得意黑 - */ -//const val FONT_FAMILY_SMILEYSANS = "SmileySans" - /** * 第三方字体-霞鹜新晰黑 */ @@ -43,8 +38,16 @@ const val FONT_FAMILY_YOZAI = "YoZai" /** - * 默认使用的语言分析模型 + * 默认使用的语言分析模型 hanlp */ const val EXTRACTION_MODEL_DEFAULT = "HanLP" -const val EXTRACTION_MODEL_GPT = "GPT-3.5" \ No newline at end of file +/** + * 默认使用的语言分析模型 gpt + */ +const val EXTRACTION_MODEL_GPT = "GPT-3.5" + +/** + * 定位功能的默认地址 + */ +const val DEFAULT_LOCATION = "获取定位失败,可选择设置默认地址" \ No newline at end of file diff --git a/app/src/main/java/com/oxyethylene/easynote/common/enumeration/ComponentSize.kt b/app/src/main/java/com/oxyethylene/easynote/common/enumeration/ComponentSize.kt new file mode 100644 index 0000000..ec99ea5 --- /dev/null +++ b/app/src/main/java/com/oxyethylene/easynote/common/enumeration/ComponentSize.kt @@ -0,0 +1,20 @@ +package com.oxyethylene.easynote.common.enumeration + +/** + * Created with IntelliJ IDEA. + * @Project : EasyNote + * @Package : com.oxyethylene.easynote.common.enumeration + * @ClassName : ComponentSize.java + * @createTime : 2024/5/8 21:59 + * @version : 1.0 + * @author : Polyoxyethylene + * @Description : + */ +/** + * 用来描述一个组件的大小 + */ +enum class ComponentSize { + + SMALL, MEDIUM, LARGE + +} \ No newline at end of file diff --git a/app/src/main/java/com/oxyethylene/easynote/dao/RecordDao.kt b/app/src/main/java/com/oxyethylene/easynote/dao/RecordDao.kt new file mode 100644 index 0000000..58b0a27 --- /dev/null +++ b/app/src/main/java/com/oxyethylene/easynote/dao/RecordDao.kt @@ -0,0 +1,37 @@ +package com.oxyethylene.easynote.dao + +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.Query +import androidx.room.Update +import com.oxyethylene.easynote.domain.entity.NoteRecord + +/** + * Created with IntelliJ IDEA. + * @Project : EasyNote + * @Package : com.oxyethylene.easynote.dao + * @ClassName : RecordDao.java + * @createTime : 2024/4/28 13:34 + * @version : 1.0 + * @author : Polyoxyethylene + * @Description : + */ +@Dao +interface RecordDao { + + @Insert + fun insertRecord (record : NoteRecord) + + /** + * 根据文章 id 删除对应记录 + */ + @Query("delete from NoteRecord where noteId = :noteId") + fun deleteRecordById (noteId: Int) + + @Query("select * from NoteRecord where noteId = :noteId") + fun getRecordById (noteId: Int) : NoteRecord + + @Update + fun updateRecord (record: NoteRecord) + +} \ No newline at end of file diff --git a/app/src/main/java/com/oxyethylene/easynote/database/AppDatabase.kt b/app/src/main/java/com/oxyethylene/easynote/database/AppDatabase.kt index 2299f27..07fb62a 100644 --- a/app/src/main/java/com/oxyethylene/easynote/database/AppDatabase.kt +++ b/app/src/main/java/com/oxyethylene/easynote/database/AppDatabase.kt @@ -6,8 +6,10 @@ import androidx.room.Room import androidx.room.RoomDatabase import com.oxyethylene.easynote.dao.EventDao import com.oxyethylene.easynote.dao.FileDao +import com.oxyethylene.easynote.dao.RecordDao import com.oxyethylene.easynote.domain.entity.Event import com.oxyethylene.easynote.domain.entity.FileEntity +import com.oxyethylene.easynote.domain.entity.NoteRecord /** * Created with IntelliJ IDEA. @@ -19,13 +21,15 @@ import com.oxyethylene.easynote.domain.entity.FileEntity * @author : Polyoxyethylene * @Description : */ -@Database(version = 1, entities = [FileEntity::class, Event::class], exportSchema = false) +@Database(version = 1, entities = [FileEntity::class, Event::class, NoteRecord::class], exportSchema = false) abstract class AppDatabase : RoomDatabase() { abstract fun FileDao() : FileDao abstract fun EventDao() : EventDao + abstract fun RecordDao() : RecordDao + companion object { private var instance: AppDatabase? = null diff --git a/app/src/main/java/com/oxyethylene/easynote/database/convertor/StringListConvertor.kt b/app/src/main/java/com/oxyethylene/easynote/database/convertor/StringListConvertor.kt new file mode 100644 index 0000000..d4c01c0 --- /dev/null +++ b/app/src/main/java/com/oxyethylene/easynote/database/convertor/StringListConvertor.kt @@ -0,0 +1,28 @@ +package com.oxyethylene.easynote.database.convertor + +import androidx.room.TypeConverter +import com.google.gson.reflect.TypeToken +import com.hjq.gson.factory.GsonFactory + +/** + * Created with IntelliJ IDEA. + * @Project : EasyNote + * @Package : com.oxyethylene.easynote.database.convertor + * @ClassName : KeywordSetConvertor.java + * @createTime : 2024/3/19 19:21 + * @version : 1.0 + * @author : Polyoxyethylene + * @Description : + */ +class StringListConvertor { + + @TypeConverter + fun stringToObject(value: String): ArrayList { + val listType = object : TypeToken>() {}.type + return GsonFactory.getSingletonGson().fromJson(value, listType) + } + + @TypeConverter + fun objectToString(list: ArrayList?): String = GsonFactory.getSingletonGson().toJson(list) + +} \ No newline at end of file diff --git a/app/src/main/java/com/oxyethylene/easynote/domain/SettingEntry.kt b/app/src/main/java/com/oxyethylene/easynote/domain/SettingEntry.kt index 5fe470a..d7715e7 100644 --- a/app/src/main/java/com/oxyethylene/easynote/domain/SettingEntry.kt +++ b/app/src/main/java/com/oxyethylene/easynote/domain/SettingEntry.kt @@ -51,7 +51,7 @@ class PlainSetting (settingName : String, val actionName: String, val commonActi * @param description 设置项的描述 * @param warning 设置项的警示信息 */ -class DialogSetting (SettingName : String, description: String? = null, warning: String? = null, val dialogAction: () -> Unit) : SettingEntry(SettingName, description, warning) +class DialogSetting (settingName : String, description: String? = null, warning: String? = null, val dialogAction: () -> Unit) : SettingEntry(settingName, description, warning) /** * 打开一个下拉菜单的设置项 diff --git a/app/src/main/java/com/oxyethylene/easynote/domain/entity/NoteRecord.kt b/app/src/main/java/com/oxyethylene/easynote/domain/entity/NoteRecord.kt new file mode 100644 index 0000000..022507f --- /dev/null +++ b/app/src/main/java/com/oxyethylene/easynote/domain/entity/NoteRecord.kt @@ -0,0 +1,31 @@ +package com.oxyethylene.easynote.domain.entity + +import androidx.room.Entity +import androidx.room.PrimaryKey +import androidx.room.TypeConverters +import com.oxyethylene.easynote.database.convertor.StringListConvertor + +/** + * Created with IntelliJ IDEA. + * @Project : EasyNote + * @Package : com.oxyethylene.easynote.domain.entity + * @ClassName : NoteRecord.java + * @createTime : 2024/4/28 13:23 + * @version : 1.0 + * @author : Polyoxyethylene + * @Description : + */ +/** + * 文章的记录 + * @param noteId 文章 id + * @param modifiedTimes 文件的修改时间,与地点一一对应 + * @param locations 文件的位置记录 + */ +@TypeConverters(StringListConvertor::class) +@Entity +class NoteRecord ( + @PrimaryKey + val noteId: Int, + val modifiedTimes: ArrayList, + val locations: ArrayList +) \ No newline at end of file diff --git a/app/src/main/java/com/oxyethylene/easynote/ui/commonactivity/BackupPageUI.kt b/app/src/main/java/com/oxyethylene/easynote/ui/commonactivity/BackupPageUI.kt index d726e1c..230b3f9 100644 --- a/app/src/main/java/com/oxyethylene/easynote/ui/commonactivity/BackupPageUI.kt +++ b/app/src/main/java/com/oxyethylene/easynote/ui/commonactivity/BackupPageUI.kt @@ -68,7 +68,7 @@ fun BackupPageUI () { val backupSettingList = listOf( DialogSetting( - SettingName = "备份/导出文件夹", + settingName = "备份/导出文件夹", description = "当前选中文件夹: ${SettingUtil.backupPath}" ) { MessageDialog.build(MIUIStyle()) diff --git a/app/src/main/java/com/oxyethylene/easynote/ui/commonactivity/KeywordPageUI.kt b/app/src/main/java/com/oxyethylene/easynote/ui/commonactivity/KeywordPageUI.kt index 26dd3c8..272ddce 100644 --- a/app/src/main/java/com/oxyethylene/easynote/ui/commonactivity/KeywordPageUI.kt +++ b/app/src/main/java/com/oxyethylene/easynote/ui/commonactivity/KeywordPageUI.kt @@ -204,9 +204,9 @@ fun onKeywordCapClick (keywordId: Int, keyword: String, onClick: () -> Unit) { "查看关联的文章" -> { MessageDialog.build(MIUIStyle()) .setTitle("关联的文章") - .setCustomView(object : OnBindView(R.layout.show_binded_notes_dialog_layout) { + .setCustomView(object : OnBindView(R.layout.compose_layout) { override fun onBind(dialog: MessageDialog?, v: View?) { - val composeView = v?.findViewById(R.id.show_notes_compose_view) + val composeView = v?.findViewById(R.id.compose_view) composeView?.setContent { ShowBindedNotesDialog(keywordId) { diff --git a/app/src/main/java/com/oxyethylene/easynote/ui/commonactivity/PrivacySettingPageUI.kt b/app/src/main/java/com/oxyethylene/easynote/ui/commonactivity/PrivacySettingPageUI.kt index 38317d7..be2ca5a 100644 --- a/app/src/main/java/com/oxyethylene/easynote/ui/commonactivity/PrivacySettingPageUI.kt +++ b/app/src/main/java/com/oxyethylene/easynote/ui/commonactivity/PrivacySettingPageUI.kt @@ -1,10 +1,54 @@ package com.oxyethylene.easynote.ui.commonactivity +import android.view.Gravity +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.expandVertically +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.animation.shrinkVertically +import androidx.compose.animation.slideInVertically +import androidx.compose.foundation.background import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.baidu.location.BDAbstractLocationListener +import com.baidu.location.BDLocation +import com.baidu.location.LocationClient +import com.baidu.location.LocationClientOption +import com.drake.net.utils.TipUtils +import com.kongzue.dialogx.dialogs.InputDialog +import com.kongzue.dialogx.dialogs.MessageDialog +import com.kongzue.dialogx.style.MIUIStyle +import com.kongzue.dialogx.util.TextInfo +import com.oxyethylene.easynote.common.constant.DEFAULT_LOCATION +import com.oxyethylene.easynote.domain.DialogSetting import com.oxyethylene.easynote.domain.SwitchSetting import com.oxyethylene.easynote.ui.components.SimpleTitleBar import com.oxyethylene.easynote.ui.settingactivity.SettingSubList +import com.oxyethylene.easynote.ui.theme.GreyLighter +import com.oxyethylene.easynote.ui.theme.LightBlue +import com.oxyethylene.easynote.ui.theme.Tomato import com.oxyethylene.easynote.util.SettingUtil /** @@ -20,24 +64,254 @@ import com.oxyethylene.easynote.util.SettingUtil @Composable fun PrivacySettingPageUI () { + // 是否显示选择定位功能相关的设置项 + var visible by remember { mutableStateOf(SettingUtil.enableLocation) } + + val density = LocalDensity.current + + val context = LocalContext.current + Column { SimpleTitleBar("隐私类功能") - SettingSubList( - listOf( - SwitchSetting ( - settingName = "文章关联定位信息", - state = SettingUtil.enableLocation, - onValueChanged = { value -> - SettingUtil.enableLocation = value - }, - description = "开启后文章将自动关联最后一次编辑时您的位置", - warning = "还没做,开了也没用" + Column (Modifier.verticalScroll(rememberScrollState())) { + + Text( + text = "请注意,Android 12 及以上的设备需要授予获取设备精确位置的权限\n否则定位功能无法正常使用(不影响应用运行)\n具体请前往应用的权限设置中进行授权", + color = Tomato, + fontSize = 12.sp, + fontWeight = FontWeight.Bold, + lineHeight = 13.sp, + modifier = Modifier.padding(top = 20.dp, start = 30.dp, end = 30.dp) + ) + + SettingSubList( + listOf( + SwitchSetting ( + settingName = "文章关联定位信息", + state = SettingUtil.enableLocation, + onValueChanged = { + SettingUtil.enableLocation = it + visible = it + }, + description = "开启后文章将自动关联最后一次编辑时您的位置", + warning = "获取位置时需要使用网络和设备定位功能\n且关闭后不会继续记录位置信息" + ) ) ) + + AnimatedVisibility( + visible = visible, + enter = slideInVertically { with(density) { -25.dp.roundToPx() } } // 从顶部 40dp 的地方开始滑入 + + expandVertically(expandFrom = Alignment.Top) // 从顶部开始展开 + + fadeIn(initialAlpha = 0.3f), // 从初始透明度 0.3f 开始淡入 + exit = shrinkVertically() + fadeOut() + ) { + + Column { + + TestLocationBlockUI() + + SettingSubList( + listOf( + DialogSetting( + settingName = "设置默认地址", + description = "当因为网络等原因未能定位成功时,将会优先使用默认地址作为记录" + ) { + val sb = StringBuffer() + if (SettingUtil.defaultLocation == DEFAULT_LOCATION) { + sb.append("当前未设置默认地址\n") + } else { + sb.append("当前默认地址为\n${SettingUtil.defaultLocation}\n") + } + sb.append("是否修改?") + MessageDialog.build(MIUIStyle()) + .setTitle("设置默认地址") + .setMessage(sb.toString()) + .setMessageTextInfo(TextInfo().setGravity(Gravity.CENTER)) + .setCancelButton("取消") + .setOkButton("修改") { + _, _ -> + InputDialog.build(MIUIStyle()) + .setTitle("修改默认地址") + .setInputText(SettingUtil.defaultLocation) + .setCancelButton("取消") + .setOkButton("确认修改") + .setOkButtonClickListener { + _, _, input -> + SettingUtil.defaultLocation = input + return@setOkButtonClickListener false + } + .show() + return@setOkButton false + } + .show() + } + ) + ) + + } + + } + + } + + } + +} + +/** + * 测试定位功能的界面 + */ +@Composable +fun TestLocationBlockUI () { + + val context = LocalContext.current + + var mLocationClient: LocationClient? = null + + var testLocation by remember { mutableStateOf("") } + + var testDescription by remember { mutableStateOf("") } + + try { + mLocationClient = LocationClient(context) + } catch (ex : Exception) { + TipUtils.toast(ex.message) + } + + val option = LocationClientOption().apply { + setIsNeedAddress(true) + } + + mLocationClient?.locOption = option + + mLocationClient?.registerLocationListener( + object : BDAbstractLocationListener() { + override fun onReceiveLocation(location: BDLocation?) { + testLocation = location?.addrStr ?: "定位失败" + if (location?.addrStr != null) { + testDescription = "定位成功" + } + mLocationClient.stop() + } + + override fun onLocDiagnosticMessage(p0: Int, p1: Int, p2: String?) { + + testDescription = "$p0 $p1 $p2\n" + when (p0) { + + 61 -> "卫星定位成功" + + 62 -> when (p1) { + 4 -> "定位失败,无法获取任何有效定位依据" + 5 -> "定位失败,无法获取有效定位依据,请检查运营商网络或者Wi-Fi网络是否正常开启,尝试重新请求定位" + 6 -> "定位失败,无法获取有效定位依据,请尝试插入一张sim卡或打开Wi-Fi重试" + 7 -> "定位失败,飞行模式下无法获取有效定位依据,请关闭飞行模式重试" + 9 -> "定位失败,无法获取任何有效定位依据" + else -> "未知错误,请联系开发者" + } + + 63 -> "网络异常,请确认当前测试手机网络是否通畅,尝试重新请求定位" + + 69 -> "定位失败,请检查定位服务开关是否打开" + + 70 -> "定位失败,请检查是否授予定位权限" + + 71 -> "定位失败,请检查定位服务开关是否打开,以及是否授予定位权限" + + 161 -> when (p1) { + 1 -> "网络定位成功,建议您打开卫星定位" + 2 -> "网络定位成功,建议您打开Wi-Fi" + else -> "未知错误,请联系开发者" + } + + 167 -> "定位失败,请确认您定位的开关打开状态,是否赋予APP定位权限" + + else -> "未知错误,请联系开发者" + + } + } + } + ) + + Column ( + Modifier.padding(start = 20.dp, top = 20.dp, end = 20.dp) + .fillMaxWidth() + .wrapContentHeight() + .clip(RoundedCornerShape(12.dp)) + .background(Color.White) + ) { + + Text( + text = "建议先单击下方按钮测试当前设备是否支持开启本应用的定位功能\n定位失败也不影响应用的使用,但是不推荐继续开启定位功能", + color = Color.Gray, + fontSize = 10.sp, + lineHeight = 12.sp, + modifier = Modifier.padding(start = 20.dp, top = 20.dp, end = 20.dp) ) + Column ( + Modifier.padding(start = 20.dp, end = 20.dp, top = 20.dp) + .fillMaxWidth() + .wrapContentHeight() + .clip(RoundedCornerShape(8.dp)) + .background(GreyLighter.copy(alpha = 0.7f)) + ) { + + Text ( + text = "定位结果", + fontSize = 10.sp, + color = Color.Gray, + modifier = Modifier.padding(start = 8.dp, top = 8.dp, bottom = 10.dp) + ) + + Text( + text = testLocation, + fontSize = 12.sp, + color = Color.DarkGray, + fontWeight = FontWeight.Bold, + modifier = Modifier.padding(start = 10.dp, end = 10.dp, top = 10.dp, bottom = 20.dp) + ) + + } + + Column ( + Modifier.padding(start = 20.dp, end = 20.dp, top = 20.dp, bottom = 20.dp) + .fillMaxWidth() + .wrapContentHeight() + .clip(RoundedCornerShape(8.dp)) + .background(GreyLighter.copy(alpha = 0.7f)) + ) { + + Text ( + text = "测试结果说明", + fontSize = 10.sp, + color = Color.Gray, + modifier = Modifier.padding(start = 8.dp, top = 8.dp, bottom = 10.dp) + ) + + Text( + text = testDescription, + fontSize = 12.sp, + color = Color.DarkGray, + fontWeight = FontWeight.Bold, + modifier = Modifier.padding(start = 10.dp, end = 10.dp, top = 10.dp, bottom = 20.dp) + ) + + } + + Button( + colors = ButtonDefaults.buttonColors(containerColor = LightBlue), + modifier = Modifier.align(alignment = Alignment.CenterHorizontally).padding(bottom = 20.dp), + onClick = { + mLocationClient?.start() + } + ) { + Text(" 测试定位 ", color = Color.White) + } + + } } \ No newline at end of file diff --git a/app/src/main/java/com/oxyethylene/easynote/ui/components/DialogContents.kt b/app/src/main/java/com/oxyethylene/easynote/ui/components/DialogContents.kt index 99f95e4..5e3796e 100644 --- a/app/src/main/java/com/oxyethylene/easynote/ui/components/DialogContents.kt +++ b/app/src/main/java/com/oxyethylene/easynote/ui/components/DialogContents.kt @@ -12,6 +12,7 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.defaultMinSize import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height @@ -25,6 +26,9 @@ import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.foundation.lazy.grid.items import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.LocationOn +import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.mutableStateListOf @@ -36,6 +40,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp @@ -646,7 +651,50 @@ fun VersionSketchDialog () { } - Text(text = "") + } + +} + +@Composable +fun RecordInfoDialog () { + + val records = NoteUtil.getRecords()!! + + LazyColumn ( + modifier = Modifier.padding(20.dp) + .height(260.dp) + .fillMaxWidth() + ) { + + itemsIndexed(records.modifiedTimes) { + index, time -> + + Row (verticalAlignment = Alignment.CenterVertically) { + + Image(painter = painterResource(R.mipmap.ic_history), contentDescription = null, modifier = Modifier.size(18.dp)) + + Text(text = time, color = Color.Gray, fontSize = 10.sp, modifier = Modifier.padding(start = 10.dp).fillMaxWidth(0.4f)) + + val location = records.locations[index] + + Row ( + modifier = Modifier.wrapContentHeight().defaultMinSize(minHeight = 40.dp), + verticalAlignment = Alignment.CenterVertically + ) { + + if (location.isNotEmpty()) { + + Icon(imageVector = Icons.Default.LocationOn, contentDescription = null, modifier = Modifier.size(22.dp), tint = Color.DarkGray) + + Text(text = location, textAlign = TextAlign.Justify, color = Color.DarkGray, fontSize = 12.sp, lineHeight = 14.sp, modifier = Modifier.padding(start = 6.dp)) + } + + } + + + } + + } } diff --git a/app/src/main/java/com/oxyethylene/easynote/ui/editactivity/EditPageUI.kt b/app/src/main/java/com/oxyethylene/easynote/ui/editactivity/EditPageUI.kt index 5bfa5fa..23a96a3 100644 --- a/app/src/main/java/com/oxyethylene/easynote/ui/editactivity/EditPageUI.kt +++ b/app/src/main/java/com/oxyethylene/easynote/ui/editactivity/EditPageUI.kt @@ -42,6 +42,7 @@ import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextDecoration +import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.kongzue.dialogx.dialogs.BottomMenu @@ -56,7 +57,9 @@ import com.kongzue.dialogx.style.MIUIStyle import com.oxyethylene.easynote.R import com.oxyethylene.easynote.common.constant.EXTRACTION_MODEL_DEFAULT import com.oxyethylene.easynote.common.constant.EXTRACTION_MODEL_GPT +import com.oxyethylene.easynote.common.enumeration.ComponentSize import com.oxyethylene.easynote.domain.NoteFile +import com.oxyethylene.easynote.ui.components.RecordInfoDialog import com.oxyethylene.easynote.ui.components.ShowKeywordsDialog import com.oxyethylene.easynote.ui.theme.GreyDarker import com.oxyethylene.easynote.ui.theme.GreyLighter @@ -85,54 +88,85 @@ import me.saket.cascade.CascadeDropdownMenu /** * 文章的标题栏 * @param noteTitle 文章的标题 + * @param keywordMap 关键词集合 * @param modifier 定制组件外观 */ -@SuppressLint("UnrememberedMutableInteractionSource") @Composable fun TitleLine(note: NoteFile, keywordMap: HashMap, modifier: Modifier) { Column ( - modifier = modifier.fillMaxWidth().wrapContentHeight().padding(start = 30.dp) + modifier = modifier.fillMaxWidth().wrapContentHeight().padding(start = 30.dp, end = 30.dp) ) { // 标题 Text( text = note.fileName, fontSize = 26.sp, + maxLines = 2, + overflow = TextOverflow.Ellipsis, fontWeight = FontWeight.ExtraBold ) - // 显示前两个绑定的关键词 - Row ( - Modifier.padding(top = 4.dp) - .clickable( - onClick = { + KeywordSketch(keywordMap, Modifier.padding(top = 4.dp)) + + Text(text = FileUtil.getNoteUpdateTime(NoteUtil.getNoteId()), fontSize = 10.sp, color = GreyDarker, modifier = Modifier.padding(top = 10.dp)) + + } + +} + +/** + * 显示省略关键词的控件 + * @param keywordMap 关键词集合 + * @param modifier 控件的位置 + * @param keywordSize 关键词的大小,默认中等,不支持 large + */ +@SuppressLint("UnrememberedMutableInteractionSource") +@Composable +fun KeywordSketch (keywordMap: HashMap, modifier: Modifier = Modifier, keywordSize: ComponentSize = ComponentSize.MEDIUM) { + + // 显示前两个绑定的关键词 + Row ( + modifier.clickable( + onClick = { MessageDialog.build(MIUIStyle()) .setTitle("相关关键词") - .setCustomView(object : OnBindView(R.layout.show_keyword_dialog_layout){ + .setCustomView(object : OnBindView(R.layout.compose_layout){ override fun onBind(dialog: MessageDialog?, v: View?) { - val composeView = v?.findViewById(R.id.show_keywords_compose_view) + val composeView = v?.findViewById(R.id.compose_view) composeView?.setContent { ShowKeywordsDialog(keywordMap) } } }) .setOkButton("确定") .show() - }, - indication = null, - interactionSource = MutableInteractionSource() - ) - ) { - keywordMap.keys.forEachIndexed { index, keyword -> - if (index < 2) { - Row (Modifier.wrapContentSize(Alignment.Center).padding(end = 10.dp).clip(RoundedCornerShape(4.dp)).background(GreyLighter)) { - Text(text = keyword, color = Color.DarkGray, fontSize = 12.sp, modifier = Modifier.padding(start = 8.dp, end = 8.dp, top = 4.dp, bottom = 4.dp)) + }, + indication = null, + interactionSource = MutableInteractionSource() + ) + ) { + keywordMap.keys.forEachIndexed { index, keyword -> + + when (keywordSize) { + ComponentSize.SMALL -> + if (index < 3) { + Row (Modifier.wrapContentSize(Alignment.Center).padding(end = 8.dp).clip(RoundedCornerShape(2.dp)).background(GreyLighter)) { + Text(text = keyword, color = Color.DarkGray, fontSize = 8.sp, modifier = Modifier.padding(start = 4.dp, end = 4.dp, top = 2.dp, bottom = 2.dp)) + } } - } + + ComponentSize.MEDIUM -> + if (index < 2) { + Row (Modifier.wrapContentSize(Alignment.Center).padding(end = 10.dp).clip(RoundedCornerShape(4.dp)).background(GreyLighter)) { + Text(text = keyword, color = Color.DarkGray, fontSize = 12.sp, modifier = Modifier.padding(start = 8.dp, end = 8.dp, top = 4.dp, bottom = 4.dp)) + } + } + + else -> {} } - if (keywordMap.isNotEmpty()) Image(painter = painterResource(R.mipmap.ic_arrow_right), contentDescription = null, modifier = Modifier.align(Alignment.CenterVertically).size(14.dp)) - } - Text(text = FileUtil.getNoteUpdateTime(NoteUtil.getNoteId()), fontSize = 10.sp, color = GreyDarker, modifier = Modifier.padding(top = 10.dp)) + + } + if (keywordMap.isNotEmpty()) Image(painter = painterResource(R.mipmap.ic_arrow_right), contentDescription = null, modifier = Modifier.align(Alignment.CenterVertically).size(14.dp)) } } @@ -380,6 +414,37 @@ fun AutoExtractionButton (modifier: Modifier = Modifier, onKeywordUpdate: () -> ) } +@SuppressLint("UnrememberedMutableInteractionSource") +@Composable +fun LocationInfoButton(modifier: Modifier) { + Image( + painter = painterResource(R.mipmap.ic_location), + contentDescription = "", + modifier = modifier.size(18.dp) + .clickable ( + onClick = { + MessageDialog.build(MIUIStyle()) + .setTitle("编辑记录\n") + .setCustomView(object : OnBindView(R.layout.compose_layout){ + override fun onBind(dialog: MessageDialog?, v: View?) { + + val composeView = v?.findViewById(R.id.compose_view) + + composeView?.setContent { + RecordInfoDialog() + } + + } + }) + .setOkButton("确定") + .show() + }, + indication = null, + interactionSource = MutableInteractionSource() + ) + ) +} + /** * 关键词和文章的绑定对话框 * @param item 指定的文章 diff --git a/app/src/main/java/com/oxyethylene/easynote/ui/eventactivity/EventInfoPageUI.kt b/app/src/main/java/com/oxyethylene/easynote/ui/eventactivity/EventInfoPageUI.kt index 17b9b25..25bd966 100644 --- a/app/src/main/java/com/oxyethylene/easynote/ui/eventactivity/EventInfoPageUI.kt +++ b/app/src/main/java/com/oxyethylene/easynote/ui/eventactivity/EventInfoPageUI.kt @@ -57,14 +57,17 @@ import com.kongzue.dialogx.style.MIUIStyle import com.kongzue.dialogx.util.InputInfo import com.kongzue.dialogx.util.TextInfo import com.oxyethylene.easynote.R +import com.oxyethylene.easynote.common.enumeration.ComponentSize import com.oxyethylene.easynote.domain.NoteFile import com.oxyethylene.easynote.domain.entity.Event import com.oxyethylene.easynote.ui.components.SimpleTitleBar +import com.oxyethylene.easynote.ui.editactivity.KeywordSketch import com.oxyethylene.easynote.ui.mainactivity.ListItem import com.oxyethylene.easynote.ui.theme.GreyLighter import com.oxyethylene.easynote.ui.theme.SkyBlue import com.oxyethylene.easynote.util.EventUtil import com.oxyethylene.easynote.util.FileUtil +import com.oxyethylene.easynote.util.KeywordUtil import me.saket.cascade.CascadeDropdownMenu /** @@ -176,7 +179,13 @@ fun EventInfoPageArea (event: Event, modifier: Modifier = Modifier) { itemsIndexed(it) { index, item -> if (item.fileId > 0) - ListItem(item, context) { onAlterButtonClick(index, item, it) } + ListItem( + item = item, + context = context, + appendix = { + KeywordSketch(KeywordUtil.getBindedKeywords(item.keywordList), Modifier.padding(start = 14.dp), keywordSize = ComponentSize.SMALL) + } + ) { onAlterButtonClick(index, item, it) } } } else { diff --git a/app/src/main/java/com/oxyethylene/easynote/ui/mainactivity/FolderListItem.kt b/app/src/main/java/com/oxyethylene/easynote/ui/mainactivity/FolderListItem.kt index e37adf2..46f5e23 100644 --- a/app/src/main/java/com/oxyethylene/easynote/ui/mainactivity/FolderListItem.kt +++ b/app/src/main/java/com/oxyethylene/easynote/ui/mainactivity/FolderListItem.kt @@ -5,12 +5,14 @@ import android.content.Intent import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.layout.wrapContentWidth import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Button @@ -56,14 +58,15 @@ import com.oxyethylene.easynote.util.NoteUtil * 普通的列表项 * @param item 列表项要使用的类对象 * @param context 应用上下文 + * @param appendix 列表项附加的 UI,位于列表项底部 * @param onAlterRequest 右侧按钮打开“更改”菜单的方法 */ @Composable -fun ListItem(item: Dentry, context: Context, onAlterRequest: () -> Unit) { +fun ListItem(item: Dentry, context: Context, appendix: @Composable() (ColumnScope.() -> Unit)? = null, onAlterRequest: () -> Unit) { - Row( + Column ( modifier = Modifier.padding(start = 20.dp, end = 20.dp, top = 12.dp) - .height(56.dp) + .wrapContentHeight() .fillMaxWidth() .clip(RoundedCornerShape(12.dp)) .background(Color.White) @@ -81,7 +84,8 @@ fun ListItem(item: Dentry, context: Context, onAlterRequest: () -> Unit) { } } ) { - Box(modifier = Modifier.padding(start = 14.dp).fillMaxSize()) { + + Box(modifier = Modifier.padding(start = 14.dp).height(56.dp).fillMaxWidth()) { // 左上角显示 文件类型图标 以及 文件名 的部分 Row(modifier = Modifier.align(Alignment.TopStart)) { @@ -111,7 +115,7 @@ fun ListItem(item: Dentry, context: Context, onAlterRequest: () -> Unit) { "创建于 ${item.createTime}", fontSize = 10.sp, color = Color.Gray, - modifier = Modifier.align(Alignment.BottomStart).padding(bottom = 10.dp) + modifier = Modifier.align(Alignment.BottomStart).padding(bottom = 8.dp) ) // 右侧正中间的 修改按钮 @@ -129,6 +133,14 @@ fun ListItem(item: Dentry, context: Context, onAlterRequest: () -> Unit) { } + appendix?.let { + Column ( + Modifier.padding(bottom = 10.dp) + ) { + it() + } + } + } } diff --git a/app/src/main/java/com/oxyethylene/easynote/ui/mainactivity/MoreFeatureButton.kt b/app/src/main/java/com/oxyethylene/easynote/ui/mainactivity/MoreFeatureButton.kt index 39a9c43..418c673 100644 --- a/app/src/main/java/com/oxyethylene/easynote/ui/mainactivity/MoreFeatureButton.kt +++ b/app/src/main/java/com/oxyethylene/easynote/ui/mainactivity/MoreFeatureButton.kt @@ -1,5 +1,6 @@ package com.oxyethylene.easynote.ui.mainactivity +import android.app.Activity import android.content.Context import android.content.Intent import android.net.Uri @@ -30,7 +31,6 @@ import androidx.compose.ui.unit.sp import com.kongzue.dialogx.dialogs.MessageDialog import com.kongzue.dialogx.dialogs.PopNotification import com.kongzue.dialogx.interfaces.OnBindView -import com.kongzue.dialogx.interfaces.OnDialogButtonClickListener import com.kongzue.dialogx.style.MIUIStyle import com.oxyethylene.easynote.R import com.oxyethylene.easynote.ui.components.MoreIcon @@ -196,31 +196,36 @@ fun MoreFeatureButton () { /** * 发起权限检查请求 * @param context 当前栈顶的 Activity + * @param mandatoryCheck 是否强制检查,强制检查意味着不通过所有权限将会导致应用闪退 */ -fun callPermissionCheck (context: Context) { +fun callPermissionCheck (context: Context, mandatoryCheck: Boolean = false) { MessageDialog.build(MIUIStyle()) .setTitle("关于权限设置") - .setCustomView(object : OnBindView(R.layout.permission_dialog_layout){ + .setCustomView(object : OnBindView(R.layout.compose_layout){ override fun onBind(dialog: MessageDialog?, v: View?) { - val composeView = v?.findViewById(R.id.permission_dialog_compose_view) + val composeView = v?.findViewById(R.id.compose_view) composeView?.setContent { PermissionDialog() } } }) + .setCancelable(!mandatoryCheck) // 强制检查将不允许直接退出对话框 .setCancelButton("取消") - .setCancelButtonClickListener { dialog, v -> false } - .setOkButton("前往检查") - .setOkButtonClickListener(object : OnDialogButtonClickListener { - override fun onClick(dialog: MessageDialog?, v: View?): Boolean { - val intent = Intent() - intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS - val uri = Uri.fromParts("package", context.packageName, null) - intent.data = uri - context.startActivity(intent) - return false + .setCancelButtonClickListener { _, _ -> + if (mandatoryCheck) { + (context as Activity).finish() } - }) + return@setCancelButtonClickListener false + } + .setOkButton("前往检查") + .setOkButtonClickListener { _, _ -> + val intent = Intent() + intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS + val uri = Uri.fromParts("package", context.packageName, null) + intent.data = uri + context.startActivity(intent) + false + } .show() } \ No newline at end of file diff --git a/app/src/main/java/com/oxyethylene/easynote/ui/settingactivity/SettingActivityUI.kt b/app/src/main/java/com/oxyethylene/easynote/ui/settingactivity/SettingActivityUI.kt index 7f1c535..7c89f0a 100644 --- a/app/src/main/java/com/oxyethylene/easynote/ui/settingactivity/SettingActivityUI.kt +++ b/app/src/main/java/com/oxyethylene/easynote/ui/settingactivity/SettingActivityUI.kt @@ -3,6 +3,8 @@ package com.oxyethylene.easynote.ui.settingactivity import android.annotation.SuppressLint import android.content.Intent import android.view.View +import androidx.compose.animation.Crossfade +import androidx.compose.animation.core.tween import androidx.compose.foundation.Image import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource @@ -88,9 +90,23 @@ fun SettingPageArea () { Column { - SettingPageTopBar("", Modifier) + val state = rememberScrollState() - Column(Modifier.verticalScroll(rememberScrollState())) { + SimpleTitleBar ( + centerContent = { + Crossfade( + targetState = state.value in 0 .. 300, + label = "", + animationSpec = tween(durationMillis = 300) + ) { + if (!it) Text(text = "设置", color = Color.DarkGray, fontSize = 16.sp, fontWeight = FontWeight.Bold) + } + } + ) { + + } + + Column(Modifier.verticalScroll(state)) { // 中间的 logo Column ( modifier = Modifier.height(260.dp).fillMaxWidth(), @@ -123,9 +139,9 @@ fun SettingPageArea () { onClick = { MessageDialog.build(MIUIStyle()) .setTitle("版本更新内容") - .setCustomView(object : OnBindView(R.layout.version_sketch_dialog_layout){ + .setCustomView(object : OnBindView(R.layout.compose_layout){ override fun onBind(dialog: MessageDialog?, v: View?) { - val composeView = v?.findViewById(R.id.version_sketch_compose_view) + val composeView = v?.findViewById(R.id.compose_view) composeView?.setContent { VersionSketchDialog() } } }) @@ -157,14 +173,6 @@ fun SettingPageArea () { } -/** - * 顶部导航栏 - * @param title 顶部的标题 - * @param modifier 设置导航栏外观 - */ -@Composable -fun SettingPageTopBar (title : String, modifier: Modifier = Modifier) = SimpleTitleBar(title, modifier) - @Composable fun SettingSubList (settingList: List, modifier: Modifier = Modifier) { @@ -222,11 +230,11 @@ fun SwitchSettingItem (entry: SwitchSetting) { Text(entry.settingName, color = Color.DarkGray, fontSize = 14.sp, fontWeight = FontWeight.Bold) entry.description?.let { Spacer(Modifier.size(4.dp)) - Text(it, color = GreyDarker, fontSize = 8.sp, maxLines = 2, lineHeight = 10.sp, fontWeight = FontWeight.Bold) + Text(it, color = GreyDarker, fontSize = 8.sp, maxLines = 3, lineHeight = 10.sp, fontWeight = FontWeight.Bold) } entry.warning?.let { Spacer(Modifier.size(4.dp)) - Text(it, color = Tomato, fontSize = 8.sp, maxLines = 2, lineHeight = 10.sp, fontWeight = FontWeight.Bold) + Text(it, color = Tomato, fontSize = 8.sp, maxLines = 3, lineHeight = 10.sp, fontWeight = FontWeight.Bold) } } @@ -278,11 +286,11 @@ fun PlainSettingItem (entry: PlainSetting) { Text(entry.settingName, color = Color.DarkGray, fontSize = 14.sp, fontWeight = FontWeight.Bold) entry.description?.let { Spacer(Modifier.size(4.dp)) - Text(it, color = GreyDarker, fontSize = 8.sp, maxLines = 2, lineHeight = 10.sp, fontWeight = FontWeight.Bold) + Text(it, color = GreyDarker, fontSize = 8.sp, maxLines = 3, lineHeight = 10.sp, fontWeight = FontWeight.Bold) } entry.warning?.let { Spacer(Modifier.size(4.dp)) - Text(it, color = Tomato, fontSize = 8.sp, maxLines = 2, lineHeight = 10.sp, fontWeight = FontWeight.Bold) + Text(it, color = Tomato, fontSize = 8.sp, maxLines = 3, lineHeight = 10.sp, fontWeight = FontWeight.Bold) } } @@ -316,11 +324,11 @@ fun DialogSettingItem (entry: DialogSetting) { Text(entry.settingName, color = Color.DarkGray, fontSize = 14.sp, fontWeight = FontWeight.Bold) entry.description?.let { Spacer(Modifier.size(4.dp)) - Text(it, color = GreyDarker, fontSize = 8.sp, maxLines = 2, lineHeight = 10.sp, fontWeight = FontWeight.Bold) + Text(it, color = GreyDarker, fontSize = 8.sp, maxLines = 3, lineHeight = 10.sp, fontWeight = FontWeight.Bold) } entry.warning?.let { Spacer(Modifier.size(4.dp)) - Text(it, color = Tomato, fontSize = 8.sp, maxLines = 2, lineHeight = 10.sp, fontWeight = FontWeight.Bold) + Text(it, color = Tomato, fontSize = 8.sp, maxLines = 3, lineHeight = 10.sp, fontWeight = FontWeight.Bold) } } @@ -357,11 +365,11 @@ fun DropDownMenuSettingItem (entry: DropDownMenuSetting, moreAction: (String) -> Text(entry.settingName, color = Color.DarkGray, fontSize = 14.sp, fontWeight = FontWeight.Bold) entry.description?.let { Spacer(Modifier.size(4.dp)) - Text(it, color = GreyDarker, fontSize = 8.sp, maxLines = 2, lineHeight = 10.sp, fontWeight = FontWeight.Bold) + Text(it, color = GreyDarker, fontSize = 8.sp, maxLines = 3, lineHeight = 10.sp, fontWeight = FontWeight.Bold) } entry.warning?.let { Spacer(Modifier.size(4.dp)) - Text(it, color = Tomato, fontSize = 8.sp, maxLines = 2, lineHeight = 10.sp, fontWeight = FontWeight.Bold) + Text(it, color = Tomato, fontSize = 8.sp, maxLines = 3, lineHeight = 10.sp, fontWeight = FontWeight.Bold) } } diff --git a/app/src/main/java/com/oxyethylene/easynote/util/CommonUtils.kt b/app/src/main/java/com/oxyethylene/easynote/util/CommonUtils.kt index 1ae8966..d30d958 100644 --- a/app/src/main/java/com/oxyethylene/easynote/util/CommonUtils.kt +++ b/app/src/main/java/com/oxyethylene/easynote/util/CommonUtils.kt @@ -20,4 +20,14 @@ import android.content.Context fun dpToPx(context: Context, dp: Int): Float { val density = context.resources.displayMetrics.density return dp * density +} + +/** + * 将 px 单位的数值转换为以 dp 做单位的对应值 + * @param context 获取设备屏幕密度 + * @param px 要转换的值 + */ +fun pxToDp(context: Context, px: Float): Int { + val density = context.resources.displayMetrics.density + return (px/density + 0.5f).toInt() } \ No newline at end of file diff --git a/app/src/main/java/com/oxyethylene/easynote/util/DateUtil.kt b/app/src/main/java/com/oxyethylene/easynote/util/DateUtil.kt index d391100..da07c5e 100644 --- a/app/src/main/java/com/oxyethylene/easynote/util/DateUtil.kt +++ b/app/src/main/java/com/oxyethylene/easynote/util/DateUtil.kt @@ -17,8 +17,10 @@ object DateUtil { // 日期时间格式 private val dateTimeFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss") - // 获取当前系统时间(字符串) - fun getCurrentDateTime() = dateTimeFormat.format(System.currentTimeMillis()) + /** + * 获取当前系统时间(字符串) + */ + fun getCurrentDateTime(): String = dateTimeFormat.format(System.currentTimeMillis()) } \ No newline at end of file diff --git a/app/src/main/java/com/oxyethylene/easynote/util/FileUtil.kt b/app/src/main/java/com/oxyethylene/easynote/util/FileUtil.kt index 1c0092d..05bc9d6 100644 --- a/app/src/main/java/com/oxyethylene/easynote/util/FileUtil.kt +++ b/app/src/main/java/com/oxyethylene/easynote/util/FileUtil.kt @@ -12,10 +12,12 @@ import com.oxyethylene.easynote.common.constant.FILE_RENAME_SUCCESS import com.oxyethylene.easynote.common.constant.FILE_UPDATE_SUCCESS import com.oxyethylene.easynote.common.enumeration.FileType import com.oxyethylene.easynote.dao.FileDao +import com.oxyethylene.easynote.dao.RecordDao import com.oxyethylene.easynote.database.AppDatabase import com.oxyethylene.easynote.domain.Dentry import com.oxyethylene.easynote.domain.Dir import com.oxyethylene.easynote.domain.NoteFile +import com.oxyethylene.easynote.domain.entity.NoteRecord import com.oxyethylene.easynote.viewmodel.MainViewModel import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -93,6 +95,8 @@ object FileUtil { */ private var fileDao: FileDao? = null + private var recordDao: RecordDao? = null + /** * 是否已经初始化,用于保证初始化目录操作只发生一次 */ @@ -112,19 +116,20 @@ object FileUtil { /** * 初始化 viewModel 和 context */ - fun initFileUtil(viewModel: MainViewModel, _database: AppDatabase, _handler: Handler) { + fun initFileUtil(viewModel: MainViewModel, database: AppDatabase, handler: Handler) { if (mainViewModel == null || mainViewModel != viewModel) { mainViewModel = viewModel } - if (database == null) { - database = _database + if (this.database == null) { + this.database = database } - if (handler == null) { - handler = _handler + if (this.handler == null) { + this.handler = handler } // 初始化 fileDao - database?.let { + this.database?.let { fileDao = it.FileDao() + recordDao = it.RecordDao() } } @@ -259,6 +264,11 @@ object FileUtil { */ fun saveFileEntry (file : Dentry) { thread { + if (file is NoteFile) { + // 首次创建一个文章时需要创建其对应的文章记录 + val record = NoteRecord(file.fileId, ArrayList(), ArrayList()) + recordDao?.insertRecord(record) + } fileDao?.insertFile(file.toFileEntity()) } } @@ -303,6 +313,8 @@ object FileUtil { (it as Dir).removeFile(deleteItem) } } + // 还需要把对应的文章记录删除 + recordDao?.deleteRecordById(it.fileId) } } // 如果删除成功,则从数据库中删除该文章的记录 @@ -585,11 +597,12 @@ object FileUtil { /** * 更新文章的修改时间 * @param fileId 文章 id + * @param updateTime 文章更新时间,只接受字符串 */ - fun setNoteUpdateTime (fileId: Int) { + fun setNoteUpdateTime (fileId: Int, updateTime: String) { fileMap.get(fileId)?.let { if (it is NoteFile) { - it.updateTime = DateUtil.getCurrentDateTime() + it.updateTime = updateTime thread { fileDao?.updateFile(it.toFileEntity()) diff --git a/app/src/main/java/com/oxyethylene/easynote/util/GPTUtil.kt b/app/src/main/java/com/oxyethylene/easynote/util/GPTUtil.kt index 5065bbc..114f792 100644 --- a/app/src/main/java/com/oxyethylene/easynote/util/GPTUtil.kt +++ b/app/src/main/java/com/oxyethylene/easynote/util/GPTUtil.kt @@ -126,9 +126,9 @@ object GPTUtil { result?.let { - FullScreenDialog.show(object : OnBindView(R.layout.text_extraction_dialog_layout){ + FullScreenDialog.show(object : OnBindView(R.layout.compose_layout){ override fun onBind(dialog: FullScreenDialog?, v: View?) { - val composeView = v?.findViewById(R.id.text_extraction_compose_view) + val composeView = v?.findViewById(R.id.compose_view) composeView?.setContent { ShowExtractionDialog( diff --git a/app/src/main/java/com/oxyethylene/easynote/util/NlpUtil.kt b/app/src/main/java/com/oxyethylene/easynote/util/NlpUtil.kt index a034098..b93fddf 100644 --- a/app/src/main/java/com/oxyethylene/easynote/util/NlpUtil.kt +++ b/app/src/main/java/com/oxyethylene/easynote/util/NlpUtil.kt @@ -105,9 +105,9 @@ object NlpUtil { CoroutineScope(Dispatchers.Main).launch { result = NLPResult(summarization?:"", keywords?.keys?: TreeSet()) WaitDialog.dismiss() - FullScreenDialog.show(object : OnBindView(R.layout.text_extraction_dialog_layout){ + FullScreenDialog.show(object : OnBindView(R.layout.compose_layout){ override fun onBind(dialog: FullScreenDialog?, v: View?) { - val composeView = v?.findViewById(R.id.text_extraction_compose_view) + val composeView = v?.findViewById(R.id.compose_view) composeView?.setContent { ShowExtractionDialog( diff --git a/app/src/main/java/com/oxyethylene/easynote/util/NoteUtil.kt b/app/src/main/java/com/oxyethylene/easynote/util/NoteUtil.kt index af02987..23f781d 100644 --- a/app/src/main/java/com/oxyethylene/easynote/util/NoteUtil.kt +++ b/app/src/main/java/com/oxyethylene/easynote/util/NoteUtil.kt @@ -2,6 +2,12 @@ package com.oxyethylene.easynote.util import android.content.Context import androidx.activity.ComponentActivity +import com.oxyethylene.easynote.dao.RecordDao +import com.oxyethylene.easynote.database.AppDatabase +import com.oxyethylene.easynote.domain.entity.NoteRecord +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import java.io.BufferedReader import java.io.BufferedWriter import java.io.FileInputStream @@ -30,21 +36,46 @@ object NoteUtil { // 文章内容的存储路径 private var notePath = "" - // 文章的内容 - var noteContent = "" + /** + * 数据库 + */ + private var database: AppDatabase? = null + + private var recordDao: RecordDao? = null + + /** + * 文章的记录 + */ + private var noteRecord: NoteRecord? = null + + /** + * 初始化 NoteUtil,传入数据库参数 + * @param database 数据库 + */ + fun initNoteUtil (database: AppDatabase) { + if (this.database == null) { + this.database = database + recordDao = database.RecordDao() + } + } /** * 在进行文章编辑之前的操作 * @param fileName 文件名 * @param fileId 文件id - */ - fun beforeEdit (fileName: String, fileId: Int) { - // 设置文章标题 - noteTitle = fileName - // 设置文章保存路径,暂时设为文件的id - notePath = fileId.toString() - noteId = fileId + */ fun beforeEdit (fileName: String, fileId: Int) { + CoroutineScope(Dispatchers.Main).launch { + // 设置文章标题 + noteTitle = fileName + // 设置文章保存路径,暂时设为文件的id + notePath = fileId.toString() + noteId = fileId + // 载入当前的文章记录 + CoroutineScope((Dispatchers.IO)).launch { + noteRecord = recordDao?.getRecordById(noteId) + } + } } /** @@ -57,6 +88,11 @@ object NoteUtil { */ fun getNoteId () = noteId + /** + * 获取当前文章的编辑记录 + */ + fun getRecords () = noteRecord + /** * 产生一个空文件 * @param path 文件路径 @@ -123,4 +159,43 @@ object NoteUtil { */ fun deleteFile (path: String, context: Context) = context.deleteFile(path) + /** + * 更新文章的记录 + * @param location 定位信息 + * @param updateTime 修改时间 + */ + fun updateRecord (location: String, updateTime: String) { + CoroutineScope(Dispatchers.Main).launch { + noteRecord?.apply { + // 如果地点没改变就只有空白字符 + if (locations.size > 0) { + var lastLocation: String? = null + var i = locations.size - 1 + // 找到上一个有效地址 + while (i >= 0) { + if (locations[i].isNotEmpty()) { + lastLocation = locations[i] + break + } + i-- + } + // 证明存在有效地址,至少是 locations[0] + if (lastLocation != null && lastLocation == location) { + locations.add("") + } else { + locations.add(location) + } + } else { + locations.add(location) + } + modifiedTimes.add(updateTime) + + // 更新数据库记录 + CoroutineScope(Dispatchers.IO).launch { + recordDao?.updateRecord(noteRecord!!) + } + } + } + } + } \ No newline at end of file diff --git a/app/src/main/java/com/oxyethylene/easynote/util/PermissionUtil.kt b/app/src/main/java/com/oxyethylene/easynote/util/PermissionUtil.kt deleted file mode 100644 index b9eb1b9..0000000 --- a/app/src/main/java/com/oxyethylene/easynote/util/PermissionUtil.kt +++ /dev/null @@ -1,91 +0,0 @@ -package com.oxyethylene.easynote.util - -import android.Manifest -import android.os.Build - -/** - * Created with IntelliJ IDEA. - * @Project : EasyNote - * @Package : com.oxyethylene.easynote.util - * @ClassName : PermissionUtil.java - * @createTime : 2024/2/23 17:06 - * @version : 1.0 - * @author : Polyoxyethylene - * @Description : 用于申请应用所需的运行时权限 - */ -object PermissionUtil { - - // 请求的运行时权限列表 - val requestList = ArrayList().apply { - add(Manifest.permission.WRITE_EXTERNAL_STORAGE) // 写外部存储 - add(Manifest.permission.READ_EXTERNAL_STORAGE) // 读外部存储 - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - add(Manifest.permission.MANAGE_EXTERNAL_STORAGE) - } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - add(Manifest.permission.READ_MEDIA_AUDIO) - add(Manifest.permission.READ_MEDIA_VIDEO) - add(Manifest.permission.READ_MEDIA_IMAGES) - } - } - - /** - * 主界面初始化时执行,请求所需运行时权限 - * 如果权限请求未通过的话直接结束活动 - * @param activity 主活动 - */ -// fun init(activity: FragmentActivity) { -// PermissionX.init(activity) -// .permissions(requestList) -// .request { allGranted, grantedList, deniedList -> -// if (!allGranted) { -// MessageDialog.build(MIUIStyle()) -// .setTitle("关于权限设置") -// .setMessageTextInfo(TextInfo().setGravity(Gravity.CENTER)) -// .setMessage(R.string.permission_request_info) -// .setCustomView(object : OnBindView(R.layout.permission_dialog_layout){ -// override fun onBind(dialog: MessageDialog?, v: View?) { -// val composeView = v?.findViewById(R.id.permission_dialog_compose_view) -// -// composeView?.setContent { PermissionDialog() } -// } -// }) -// .setCancelButton("拒绝") -// .setCancelButtonClickListener(object : OnDialogButtonClickListener { -// override fun onClick(dialog: MessageDialog?, v: View?): Boolean { -//// activity.finish() -// return false -// } -// }) -// .setOkButton("同意") -// .setOkButtonClickListener(object : OnDialogButtonClickListener { -// override fun onClick(dialog: MessageDialog?, v: View?): Boolean { -// val intent = Intent() -// intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS -// val uri = Uri.fromParts("package", activity.packageName, null) -// intent.data = uri -// activity.startActivity(intent) -// return false -// } -// }) -// .show() -// } -// } -// } - - /** - * 对应用所请求权限是否全部通过的再检查 - * @param activity 主活动 - */ -// fun checkAgain (activity: FragmentActivity) { -// PermissionX.init(activity) -// .permissions(requestList) -// .request { allGranted, grantedList, deniedList -> -// if (!allGranted) { -// activity.finish() -// } -// } -// } - -} \ No newline at end of file diff --git a/app/src/main/java/com/oxyethylene/easynote/util/SettingUtil.kt b/app/src/main/java/com/oxyethylene/easynote/util/SettingUtil.kt index f1bc487..799ad7f 100644 --- a/app/src/main/java/com/oxyethylene/easynote/util/SettingUtil.kt +++ b/app/src/main/java/com/oxyethylene/easynote/util/SettingUtil.kt @@ -1,6 +1,7 @@ package com.oxyethylene.easynote.util import com.drake.serialize.serialize.serialLazy +import com.oxyethylene.easynote.common.constant.DEFAULT_LOCATION import com.oxyethylene.easynote.common.constant.EASYNOTE_BACKUP_FOLDER import com.oxyethylene.easynote.common.constant.EXTRACTION_MODEL_DEFAULT import com.oxyethylene.easynote.common.constant.FONT_FAMILY_DEFAULT @@ -65,4 +66,9 @@ object SettingUtil { */ var enableLocation by serialLazy(false) + /** + * 默认定位地址 + */ + var defaultLocation by serialLazy(DEFAULT_LOCATION) + } \ No newline at end of file diff --git a/app/src/main/res/layout/show_binded_notes_dialog_layout.xml b/app/src/main/res/layout/compose_layout.xml similarity index 61% rename from app/src/main/res/layout/show_binded_notes_dialog_layout.xml rename to app/src/main/res/layout/compose_layout.xml index 5d706fa..582d4eb 100644 --- a/app/src/main/res/layout/show_binded_notes_dialog_layout.xml +++ b/app/src/main/res/layout/compose_layout.xml @@ -1,11 +1,11 @@ + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent"> diff --git a/app/src/main/res/layout/permission_dialog_layout.xml b/app/src/main/res/layout/permission_dialog_layout.xml deleted file mode 100644 index f396e6c..0000000 --- a/app/src/main/res/layout/permission_dialog_layout.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/show_keyword_dialog_layout.xml b/app/src/main/res/layout/show_keyword_dialog_layout.xml deleted file mode 100644 index a530afd..0000000 --- a/app/src/main/res/layout/show_keyword_dialog_layout.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/text_extraction_dialog_layout.xml b/app/src/main/res/layout/text_extraction_dialog_layout.xml deleted file mode 100644 index bc18313..0000000 --- a/app/src/main/res/layout/text_extraction_dialog_layout.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/version_sketch_dialog_layout.xml b/app/src/main/res/layout/version_sketch_dialog_layout.xml deleted file mode 100644 index 82e7501..0000000 --- a/app/src/main/res/layout/version_sketch_dialog_layout.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/mipmap-xxhdpi/ic_history.webp b/app/src/main/res/mipmap-xxhdpi/ic_history.webp new file mode 100644 index 0000000..7ade75f Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_history.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_location.webp b/app/src/main/res/mipmap-xxhdpi/ic_location.webp new file mode 100644 index 0000000..477fdad Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_location.webp differ