Compare commits

..

5 Commits

Author SHA1 Message Date
3f9b2484bb feat(app): 添加相册快捷入口并优化文件管理功能
- 在菜单栏添加相册快捷入口,提高用户体验
- 移除冗余代码,优化文件管理活动- 更新菜单资源,增加相册快捷项
- 添加相册图标资源
- 修正版权年份为动态显示
2025-02-11 18:17:34 +08:00
a0baf28cd2 refactor(mod): 重构模组相关功能
- 移除了 BottomSheet 类
- 优化了 CreationWizardActivity 的逻辑
- 更新了 ModFragment 的实现,提高了代码可读性和性能
- 简化了 WarehouseFragment 的代码
- 删除了未使用的 SettingsActivity 导入
2025-02-11 18:01:32 +08:00
7c46656e0a
refactor(Mod): 移除未实现的功能入口
- 从 ModActionAdapter 中移除了"发布"和"作品首页"选项
- 从 ModFragment 中移除了"作品首页"选项
- 删除了相关无用代码和未实现的方法
2025-02-10 22:16:11 +08:00
c55d77cf6f
feat(app): 更新导入功能和权限请求逻辑
- 修改导入完成提示文本
- 更新应用版本号至1.0.1
-修复权限请求完成后未调用回调函数的问题
- 在WarehouseFragment中添加权限请求逻辑
- 新增导入提示字符串资源
2025-02-10 22:10:35 +08:00
f392dc98b7
refactor(app): 删除无用的布局文件和活动代码
- 删除了 ErrorActivity、RegisterActivity 和 ReportActivity 的布局文件
- 删除了 CreateModActivity、RecyclingStationActivity、WarehouseFragment 中的无用代码
- 优化了 TabLayout 的配置
- 添加了新的字符串资源
2025-02-10 21:56:36 +08:00
27 changed files with 263 additions and 1536 deletions

View File

@ -25,8 +25,8 @@ android {
applicationId "com.coldmint.rust.lite"
minSdkVersion 23
targetSdkVersion 34
versionCode 1
versionName "1.0"
versionCode 2
versionName "1.0.1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

View File

@ -7220,7 +7220,7 @@ androidx.media.R$style
kotlin.UNumbersKt
kotlin.reflect.TypeVariableImpl
androidx.appcompat.widget.TooltipCompatHandler$1
com.coldmint.rust.pro.CreateModActivity
com.coldmint.rust.pro.Activity
kotlin.collections.MapsKt__MapsJVMKt
androidx.appcompat.widget.ToolbarWidgetWrapper$1
com.bumptech.glide.load.model.ByteArrayLoader$StreamFactory

View File

@ -70,9 +70,8 @@ class AboutActivity : BaseActivity<ActivityAboutBinding>() {
}
override fun getViewBindingObject(layoutInflater: LayoutInflater): ActivityAboutBinding {
return ActivityAboutBinding.inflate(layoutInflater)
}
override fun getViewBindingObject(layoutInflater: LayoutInflater): ActivityAboutBinding =
ActivityAboutBinding.inflate(layoutInflater)
override fun whenCreateActivity(savedInstanceState: Bundle?, canUseView: Boolean) {
if (canUseView) {

View File

@ -114,29 +114,23 @@ class CreateModActivity : BaseActivity<ActivityCreateModBinding>() {
stringBuilder.append("\nminVersion: ")
stringBuilder.append(minVersion)
}
GlobalMethod.requestStoragePermissions(this@CreateModActivity) {
if (!it) {
return@requestStoragePermissions
}
val mod_directory =
val modDirectory =
File(Environment.getExternalStorageDirectory().absolutePath + "/rustedWarfare/units/" + name)
if (mod_directory.exists()) {
if (modDirectory.exists()) {
setErrorAndInput(
viewBinding.modNameEdit,
getString(R.string.directory_error),
viewBinding.modNameInputLayout
)
} else {
if (mod_directory.mkdirs()) {
val fileWriter = FileWriter(mod_directory.absolutePath + "/mod-info.txt")
if (modDirectory.mkdirs()) {
val fileWriter = FileWriter(modDirectory.absolutePath + "/mod-info.txt")
fileWriter.write(stringBuilder.toString())
fileWriter.close()
setResult(RESULT_OK)
finish()
}
}
}
})
}

View File

@ -1,14 +1,10 @@
package com.coldmint.rust.pro
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.coldmint.rust.core.debug.LogCat
import com.coldmint.rust.pro.adapters.GuideAdapter
import com.coldmint.rust.pro.base.BaseActivity
@ -19,10 +15,7 @@ import com.coldmint.rust.pro.ui.StableLinearLayoutManager
class CreationWizardActivity : BaseActivity<ActivityCreationWizardBinding>() {
lateinit var createMod: ActivityResultLauncher<Intent>
//创建向导类型(模组,模板包)
lateinit var type: String
private lateinit var createMod: ActivityResultLauncher<Intent>
override fun whenCreateActivity(savedInstanceState: Bundle?, canUseView: Boolean) {
setReturnButton()
title = getString(R.string.creation_assistant)
@ -34,59 +27,14 @@ class CreationWizardActivity : BaseActivity<ActivityCreationWizardBinding>() {
LogCat.d("创建单位", "没有收到数据。")
}
}
val temType = intent.getStringExtra("type")
if (temType.isNullOrBlank()) {
showToast("请传入类型")
finish()
return
}
type = temType
viewBinding.recyclerView.layoutManager = StableLinearLayoutManager(this)
when (temType) {
"mod" -> {
loadMod()
}
"template" -> {
loadTemplate()
}
}
}
/**
* 加载模板活动
*/
private fun loadTemplate() {
val dataList = ArrayList<GuideData>()
dataList.add(
GuideData(
R.string.import_template,
R.string.import_template_describe,
R.drawable.folder
)
)
val adapter = GuideAdapter(this, dataList)
adapter.setItemEvent { i, itemGuideBinding, viewHolder, guideData ->
itemGuideBinding.root.setOnClickListener {
finish()
when (guideData.titleRes) {
R.string.import_template -> {
val startIntent =
Intent(this, FileManagerActivity::class.java)
val fileBundle = Bundle()
fileBundle.putString("type", "selectFile")
startIntent.putExtra("data", fileBundle)
startActivity(startIntent)
}
}
}
}
viewBinding.recyclerView.adapter = adapter
}
/**
* 加载模组活动
*/
fun loadMod() {
private fun loadMod() {
val dataList = ArrayList<GuideData>()
dataList.add(
GuideData(
@ -128,6 +76,7 @@ class CreationWizardActivity : BaseActivity<ActivityCreationWizardBinding>() {
)
createMod.launch(startActivity)
}
R.string.import_mod -> {
val startIntent =
Intent(this, FileManagerActivity::class.java)
@ -137,6 +86,7 @@ class CreationWizardActivity : BaseActivity<ActivityCreationWizardBinding>() {
startActivity(startIntent)
finish()
}
R.string.import_mod_from_package_directory -> {
val startIntent =
Intent(this, FileManagerActivity::class.java)
@ -152,6 +102,7 @@ class CreationWizardActivity : BaseActivity<ActivityCreationWizardBinding>() {
startActivity(startIntent)
finish()
}
R.string.import_mod_from_recycle_bin -> {
startActivity(Intent(this, RecyclingStationActivity::class.java))
finish()

View File

@ -6,7 +6,6 @@ import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.MenuItem
import cat.ereza.customactivityoncrash.CustomActivityOnCrash
import com.coldmint.rust.core.debug.LogCat
import com.coldmint.rust.core.tool.FileOperator
import com.coldmint.rust.pro.base.BaseActivity
import com.coldmint.rust.pro.databean.ErrorInfo
@ -19,7 +18,6 @@ class ErrorActivity : BaseActivity<ActivityErrorBinding>() {
ErrorInfo()
}
private fun initView() {
setTitle(R.string.collapse_info)
val title = String.format(getString(R.string.error_title), getString(R.string.app_name))
@ -37,7 +35,6 @@ class ErrorActivity : BaseActivity<ActivityErrorBinding>() {
errorInfo.activityLog = CustomActivityOnCrash.getActivityLogFromIntent(intent)
}
viewBinding.errorInfo.text = errorInfo.allErrorDetails
LogCat.e("错误日志", errorInfo.allErrorDetails)
saveLog()
}
}

View File

@ -41,128 +41,30 @@ import java.io.File
class FileManagerActivity : BaseActivity<ActivityFileBinding>() {
//
// /**
// * 编辑模板
// * @param file File
// */
// fun editTemplate(file: File) {
// val intent = Intent(this, TemplateMakerActivity::class.java)
// val bundle = Bundle()
// intent.putExtra("data", bundle)
// bundle.putString("path", file.absolutePath)
// bundle.putBoolean("loadTemplate", true)
// bundle.putString("templatePath", additionalData)
// startActivity(intent)
// }
//
// /**
// * 编辑文本
// * @param file File
// */
// fun editText(file: File) {
// val bundle = Bundle()
// bundle.putString("path", file.absolutePath)
// bundle.putString(
// "modPath",
// FileOperator.getSuperDirectory(file)
// )
// val intent = Intent(
// this@FileManagerActivity,
// EditActivity::class.java
// )
// intent.putExtra("data", bundle)
// this@FileManagerActivity.startActivity(intent)
// }
// override fun onPause() {
// viewModel.getBookmarkManager().save()
// super.onPause()
// }
override fun onResume() {
viewModel.getBookmarkManager().load()
loadMineBookmarksMenu()
super.onResume()
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == RESULT_OK) {
if (viewModel.startTypeData == FileManagerViewModel.StartType.SELECT_FILE && requestCode == 1) {
// val path = FileOperator.parsePicturePath(this@FileManagerActivity, data)
// if (path != null) {
// val intent = Intent()
// intent.putExtra("File", path)
// setResult(RESULT_OK, intent)
// finish()
// }
} else if (viewModel.startTypeData == FileManagerViewModel.StartType.SELECT_FILE && requestCode == 2) {
// val path = viewModel.parseFilePath(this@FileManagerActivity, data)
// if (path != null) {
// val intent = Intent()
// intent.putExtra("File", path)
// setResult(RESULT_OK, intent)
//// bookmarkManager.save()
// finish()
// }
}
// else if (requestCode == 3) {
//新建源文件
// loadFiles(directs)
// } else if (requestCode == 4) {
// val file = File(data!!.getStringExtra("File"))
// val copyResult =
// FileOperator.copyFile(file, File(directs.toString() + "/" + file.name))
// if (!copyResult) {
// Snackbar.make(
// viewBinding.fab,
// getText(R.string.copy_file_error),
// Snackbar.LENGTH_SHORT
// ).show()
// } else {
// loadFiles(directs)
// }
// }
}
}
lateinit var photoAlbumResultLauncher: ActivityResultLauncher<Intent>
lateinit var systemFileManagerResultLauncher: ActivityResultLauncher<String>
//
override fun onOptionsItemSelected(item: MenuItem): Boolean {
val id = item.itemId
when (id) {
android.R.id.home -> {
// bookmarkManager.save()
finish()
return true
}
R.id.reloadFile -> {
viewModel.loadFiles(viewModel.getCurrentPath())
return true
}
// R.id.photo_album -> {
// this@FileManagerActivity.startActivityForResult(
// Intent(
// Intent.ACTION_PICK,
// MediaStore.Images.Media.EXTERNAL_CONTENT_URI
// ), 1
// )
// return true
// }
// R.id.system_file_manager -> {
// val intent = Intent(Intent.ACTION_GET_CONTENT)
// intent.type = "*/*"
// intent.addCategory(Intent.CATEGORY_OPENABLE)
// this@FileManagerActivity.startActivityForResult(intent, 2)
// return true
// }
}
// loadBook(item.title)
return super.onOptionsItemSelected(item)
}
@ -182,33 +84,6 @@ class FileManagerActivity : BaseActivity<ActivityFileBinding>() {
viewBinding.fab.setOnClickListener {
val startType = viewModel.startTypeData
when (startType) {
// "exportFile" -> {
// val oldFile = File(additionalData)
// val result = FileOperator.copyFile(
// oldFile,
// File(directs.absolutePath + "/" + oldFile.name)
// )
// if (result) {
// setResult(RESULT_OK)
// }
// finish()
// }
// "selectDirectents" -> {
// intent.putExtra("Directents", directs.absolutePath)
// setResult(RESULT_OK, intent)
// bookmarkManager.save()
// finish()
// }
// "selectFile" -> {
// intent.putExtra("File", filePath)
// setResult(RESULT_OK, intent)
// bookmarkManager.save()
// finish()
// }
// FileManagerViewModel.StartType.SELECT_FILE -> {
//
// }
FileManagerViewModel.StartType.DEFAULT, FileManagerViewModel.StartType.SELECT_FILE, FileManagerViewModel.StartType.SELECT_DIRECTORY -> {
var popupMenu = GlobalMethod.createPopMenu(viewBinding.fab)
if (adapter != null) {
@ -226,7 +101,6 @@ class FileManagerActivity : BaseActivity<ActivityFileBinding>() {
popupMenu.menu.add(R.string.select_file)
popupMenu.setOnMenuItemClickListener { item ->
val title = item.title
// val handler = Handler(Looper.getMainLooper())
when (title) {
getText(R.string.create_unit) -> {
val intent =
@ -237,6 +111,7 @@ class FileManagerActivity : BaseActivity<ActivityFileBinding>() {
intent.putExtra("data", bundle)
startActivityForResult(intent, 3)
}
getText(R.string.select_file) -> {
val bundle = Bundle()
val intent =
@ -249,9 +124,11 @@ class FileManagerActivity : BaseActivity<ActivityFileBinding>() {
intent.putExtra("data", bundle)
startActivityForResult(intent, 4)
}
getText(R.string.create_folder) -> {
createFolderAction()
}
getText(R.string.copy_to_this) -> {
val job = Job()
val handler = Handler(Looper.getMainLooper())
@ -281,6 +158,7 @@ class FileManagerActivity : BaseActivity<ActivityFileBinding>() {
}
}
}
getText(R.string.cut_to_this) -> {
val job = Job()
val handler = Handler(Looper.getMainLooper())
@ -314,126 +192,14 @@ class FileManagerActivity : BaseActivity<ActivityFileBinding>() {
}
popupMenu.show()
}
else -> {
}
}
}
}
//
// /**
// * 创建文件夹活动
// */
// private fun createFolderAction() {
// MaterialDialog(this).show {
// title(R.string.create_folder)
// input(
// maxLength = 255,
// waitForPositiveButton = false
// ) { dialog, text ->
// if (text.length in 1..255) {
// dialog.setActionButtonEnabled(WhichButton.POSITIVE, true)
// }
// }.positiveButton(R.string.dialog_ok, null) { dialog ->
// val string = dialog.getInputField().text.toString()
// val file = File("$directs/$string")
// if (file.exists()) {
// Toast.makeText(
// this@FileManagerActivity,
// R.string.folder_error,
// Toast.LENGTH_SHORT
// ).show()
// } else {
// file.mkdirs()
// loadFiles(directs)
// }
// }.negativeButton(R.string.dialog_close)
// }
// }
//
//
//
// private fun getPath(context: Context, uri: Uri?): String? {
// val isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT
//
// // DocumentProvider
// if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
// // ExternalStorageProvider
// if (isExternalStorageDocument(uri)) {
// val docId = DocumentsContract.getDocumentId(uri)
// val split = docId.split(":").toTypedArray()
// val type = split[0]
// if ("primary".equals(type, ignoreCase = true)) {
// return Environment.getExternalStorageDirectory().toString() + "/" + split[1]
// }
// } else if (isDownloadsDocument(uri)) {
// val id = DocumentsContract.getDocumentId(uri)
// val contentUri = ContentUris.withAppendedId(
// Uri.parse("content://downloads/public_downloads"),
// java.lang.Long.valueOf(id)
// )
// return getDataColumn(context, contentUri, null, null)
// } else if (isMediaDocument(uri)) {
// val docId = DocumentsContract.getDocumentId(uri)
// val split = docId.split(":").toTypedArray()
// val type = split[0]
// var contentUri: Uri? = null
// if ("image" == type) {
// contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
// } else if ("video" == type) {
// contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
// } else if ("audio" == type) {
// contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
// }
// val selection = "_id=?"
// val selectionArgs = arrayOf(split[1])
// return getDataColumn(context, contentUri, selection, selectionArgs)
// }
// } else if ("content".equals(uri!!.scheme, ignoreCase = true)) {
// return getDataColumn(context, uri, null, null)
// } else if ("file".equals(uri.scheme, ignoreCase = true)) {
// uri.path
// }
// return null
// }
//
// private fun isMediaDocument(uri: Uri?): Boolean {
// return "com.android.providers.media.documents" == uri!!.authority
// }
//
// private fun isExternalStorageDocument(uri: Uri?): Boolean {
// return "com.android.externalstorage.documents" == uri!!.authority
// }
//
// private fun isDownloadsDocument(uri: Uri?): Boolean {
// return "com.android.providers.downloads.documents" == uri!!.authority
// }
//
// private fun getDataColumn(
// context: Context,
// uri: Uri?,
// selection: String?,
// selectionArgs: Array<String>?
// ): String? {
// var cursor: Cursor? = null
// val column = "_data"
// val projection = arrayOf(column)
// try {
// cursor = context.contentResolver.query(
// uri!!, projection, selection, selectionArgs,
// null
// )
// if (cursor != null && cursor.moveToFirst()) {
// val column_index = cursor.getColumnIndexOrThrow(column)
// return cursor.getString(column_index)
// }
// } finally {
// cursor?.close()
// }
// return null
// }
//
private lateinit var menuBinding: MenuBinding
private val viewModel: FileManagerViewModel by lazy {
ViewModelProvider(this).get(FileManagerViewModel::class.java)
@ -493,7 +259,8 @@ class FileManagerActivity : BaseActivity<ActivityFileBinding>() {
override fun whenCreateActivity(savedInstanceState: Bundle?, canUseView: Boolean) {
if (canUseView) {
setReturnButton()
viewBinding.recyclerView.layoutManager = StableLinearLayoutManager(this@FileManagerActivity)
viewBinding.recyclerView.layoutManager =
StableLinearLayoutManager(this@FileManagerActivity)
val linearLayoutManager = StableLinearLayoutManager(this)
linearLayoutManager.orientation = LinearLayoutManager.HORIZONTAL
viewBinding.fileTabNav.layoutManager = linearLayoutManager
@ -539,6 +306,7 @@ class FileManagerActivity : BaseActivity<ActivityFileBinding>() {
}.setGestureInsetBottomIgnored(true).show()
FileManagerViewModel.StartType.SELECT_DIRECTORY
}
"exportFile" -> {
Snackbar.make(
viewBinding.fab,
@ -557,9 +325,11 @@ class FileManagerActivity : BaseActivity<ActivityFileBinding>() {
}.setGestureInsetBottomIgnored(true).show()
FileManagerViewModel.StartType.EXPORT_FILE
}
"selectFile" -> {
FileManagerViewModel.StartType.SELECT_FILE
}
else -> {
FileManagerViewModel.StartType.DEFAULT
}
@ -586,7 +356,7 @@ class FileManagerActivity : BaseActivity<ActivityFileBinding>() {
systemFileManagerResultLauncher.launch("*/*")
true
}
menuBinding.photoAlbumItem.setOnMenuItemClickListener {
val photoAlbumOnMenuItemClickListener = { _: MenuItem ->
val intent = Intent(
Intent.ACTION_PICK,
MediaStore.Images.Media.EXTERNAL_CONTENT_URI
@ -594,6 +364,10 @@ class FileManagerActivity : BaseActivity<ActivityFileBinding>() {
photoAlbumResultLauncher.launch(intent)
true
}
menuBinding.photoAlbumItemShortcut.setOnMenuItemClickListener(
photoAlbumOnMenuItemClickListener
)
menuBinding.photoAlbumItem.setOnMenuItemClickListener(photoAlbumOnMenuItemClickListener)
menuBinding.actionSortByType.setOnMenuItemClickListener {
viewModel.sortTypeLiveData.value = FileManagerViewModel.SortType.BY_TYPE
true
@ -776,6 +550,7 @@ class FileManagerActivity : BaseActivity<ActivityFileBinding>() {
viewModel.getBookmarkManager().save()
loadMineBookmarksMenu()
}
R.id.renameAction -> {
val finalFile =
adapter!!.getItemData(viewHolder.absoluteAdapterPosition)
@ -798,6 +573,7 @@ class FileManagerActivity : BaseActivity<ActivityFileBinding>() {
}.setCancelable(false).show()
}
R.id.deleteAction -> {
val finalFile =
adapter!!.getItemData(viewHolder.absoluteAdapterPosition)
@ -816,11 +592,13 @@ class FileManagerActivity : BaseActivity<ActivityFileBinding>() {
}.show()
}
R.id.copyAction -> {
val finalFile =
adapter!!.getItemData(viewHolder.absoluteAdapterPosition)
adapter!!.setSelectPath(finalFile!!.absolutePath, true)
}
R.id.cutOffAction -> {
val finalFile =
adapter!!.getItemData(viewHolder.absoluteAdapterPosition)
@ -889,15 +667,19 @@ class FileManagerActivity : BaseActivity<ActivityFileBinding>() {
FileManagerViewModel.SortType.BY_NAME -> {
menuBinding.actionSortByName.isChecked = true
}
FileManagerViewModel.SortType.BY_SIZE -> {
menuBinding.actionSortBySize.isChecked = true
}
FileManagerViewModel.SortType.BY_LAST_MODIFIED -> {
menuBinding.actionSortByLastModified.isChecked = true
}
FileManagerViewModel.SortType.BY_TYPE -> {
menuBinding.actionSortByType.isChecked = true
}
else -> {
menuBinding.actionSortByName.isChecked = true
}
@ -916,6 +698,7 @@ class FileManagerActivity : BaseActivity<ActivityFileBinding>() {
FileManagerViewModel.StartType.DEFAULT -> {
getString(R.string.file_manager)
}
else -> {
getString(R.string.file_manager)
}
@ -931,6 +714,7 @@ class FileManagerActivity : BaseActivity<ActivityFileBinding>() {
val menu: Menu,
val reloadFileItem: MenuItem,
val photoAlbumItem: MenuItem,
val photoAlbumItemShortcut: MenuItem,
val systemFileManagerItem: MenuItem,
val actionSortByName: MenuItem,
val actionSortByType: MenuItem,
@ -947,6 +731,7 @@ class FileManagerActivity : BaseActivity<ActivityFileBinding>() {
menu,
menu.findItem(R.id.reloadFile),
menu.findItem(R.id.photo_album),
menu.findItem(R.id.photo_album_shortcut),
menu.findItem(R.id.system_file_manager),
menu.findItem(R.id.action_sort_by_name),
menu.findItem(R.id.action_sort_by_type),

View File

@ -15,6 +15,7 @@ import com.coldmint.rust.pro.adapters.FileAdapter
import com.coldmint.rust.pro.databinding.ActivityRecyclingStationBinding
import com.coldmint.rust.pro.tool.GlobalMethod
import com.coldmint.rust.pro.ui.StableLinearLayoutManager
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import java.io.File
import java.util.ArrayList
@ -81,6 +82,10 @@ class RecyclingStationActivity : BaseActivity<ActivityRecyclingStationBinding>()
}
val title = item.title.toString()
if (title == getString(R.string.delete_title)) {
MaterialAlertDialogBuilder(this@RecyclingStationActivity)
.setTitle(R.string.delete_title).setCancelable(false)
.setMessage(R.string.delete_confirm)
.setPositiveButton(R.string.dialog_ok) { _, _ ->
Thread {
working = true
FileOperator.delete_files(file)
@ -89,6 +94,9 @@ class RecyclingStationActivity : BaseActivity<ActivityRecyclingStationBinding>()
loadFiles()
}
}.start()
}
.setNegativeButton(R.string.dialog_cancel) { _, _ -> }
.show()
} else if (title == getString(R.string.recovery_file)) {
Thread {
working = true
@ -139,6 +147,10 @@ class RecyclingStationActivity : BaseActivity<ActivityRecyclingStationBinding>()
val id = item.itemId
when (id) {
R.id.clear_recovery_station -> {
MaterialAlertDialogBuilder(this)
.setTitle(R.string.clear_recovery_station)
.setMessage(R.string.clear_recovery_station_message).setCancelable(false)
.setPositiveButton(R.string.dialog_ok) { _, _ ->
Thread {
runOnUiThread {
viewBinding.progressBar.isVisible = true
@ -154,8 +166,12 @@ class RecyclingStationActivity : BaseActivity<ActivityRecyclingStationBinding>()
viewBinding.backupError.setText(R.string.not_find_mod)
}
}.start()
}
.setNegativeButton(R.string.dialog_cancel, null)
.show()
return true
}
R.id.restore_all -> {
Thread {
runOnUiThread {

View File

@ -1,425 +0,0 @@
package com.coldmint.rust.pro
import android.os.Bundle
import android.text.Editable
import android.text.InputType
import android.text.TextWatcher
import android.view.LayoutInflater
import com.coldmint.rust.pro.base.BaseActivity
import android.view.View
import androidx.core.view.isVisible
import com.coldmint.dialog.CoreDialog
import com.coldmint.rust.pro.tool.AppSettings
import com.coldmint.rust.pro.tool.GlobalMethod
import com.coldmint.rust.core.interfaces.ApiCallBack
import com.coldmint.rust.core.web.ServerConfiguration
import com.coldmint.rust.core.dataBean.ApiResponse
import com.coldmint.rust.core.dataBean.RegisterRequestData
import com.coldmint.rust.core.web.User
import com.coldmint.rust.pro.databinding.ActivityRegisterBinding
import com.coldmint.rust.pro.tool.EmailAutoCompleteHelper
import com.google.android.material.snackbar.Snackbar
class RegisterActivity : BaseActivity<ActivityRegisterBinding>() {
private var isRegister = false
private fun initAction() {
viewBinding.userNameView.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
override fun afterTextChanged(s: Editable?) {
val userName = s.toString()
checkUserName(userName)
setRegisterButtonEnable()
}
})
viewBinding.accountView.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
override fun afterTextChanged(s: Editable?) {
val account = s.toString()
checkAccount(account)
setRegisterButtonEnable()
}
})
viewBinding.passwordView.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
override fun afterTextChanged(s: Editable?) {
val passWord = s.toString()
checkPassword(passWord)
setRegisterButtonEnable()
}
})
viewBinding.confirmPasswordView.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {
}
override fun afterTextChanged(p0: Editable?) {
val confirmPassword = p0.toString()
checkConfirmPassword(confirmPassword)
setRegisterButtonEnable()
}
})
viewBinding.emailView.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
override fun afterTextChanged(s: Editable?) {
val email = s.toString()
checkEmail(email)
setRegisterButtonEnable()
}
})
val emailAutoCompleteHelper = EmailAutoCompleteHelper(this)
emailAutoCompleteHelper.onBindAutoCompleteTextView(viewBinding.emailView)
viewBinding.registerButton.setOnClickListener(View.OnClickListener { v ->
inputMethodManager.hideSoftInputFromWindow(v.windowToken, 0)
if (!isRegister) {
val account = viewBinding.accountView.text.toString()
val passWord = viewBinding.passwordView.text.toString()
val userName = viewBinding.userNameView.text.toString()
val email = viewBinding.emailView.text.toString()
val confirmPassword = viewBinding.confirmPasswordView.text.toString()
if (!checkConfirmPassword(confirmPassword)) {
return@OnClickListener
}
if (!checkAccount(account)) {
return@OnClickListener
}
if (!checkUserName(userName)) {
return@OnClickListener
}
if (!checkPassword(passWord)) {
return@OnClickListener
}
if (!checkEmail(email)) {
return@OnClickListener
}
isRegister = true
viewBinding.registerButton.setBackgroundColor(
GlobalMethod.getThemeColor(
this@RegisterActivity,
com.google.android.material.R.attr.colorPrimaryVariant
)
)
viewBinding.registerButton.setText(R.string.request_data)
val appID = AppSettings.getValue(AppSettings.Setting.AppID, "")
User.register(
RegisterRequestData(account, passWord, userName, email, appID),
object : ApiCallBack<ApiResponse> {
override fun onResponse(apiResponse: ApiResponse) {
isRegister = false
viewBinding.registerButton.setBackgroundColor(
GlobalMethod.getColorPrimary(
this@RegisterActivity
)
)
viewBinding.registerButton.setText(R.string.register)
if (apiResponse.code == ServerConfiguration.Success_Code) {
AppSettings.forceSetValue(AppSettings.Setting.Account, account)
AppSettings.forceSetValue(AppSettings.Setting.PassWord, passWord)
AppSettings.forceSetValue(AppSettings.Setting.UserName, userName)
CoreDialog(this@RegisterActivity).setTitle(R.string.register_successed)
.setMessage(R.string.registration_success_message)
.setCancelable(false).setPositiveButton(R.string.close) {
finish()
}.show()
} else {
val data = apiResponse.data
if (data != null && ServerConfiguration.isEvent(data)) {
when (data) {
"@event:账号占用" -> {
setErrorAndInput(
viewBinding.accountView,
getString(R.string.account_error2),
viewBinding.accountInputLayout
)
}
"@event:用户名占用" -> {
setErrorAndInput(
viewBinding.userNameView,
getString(R.string.user_name_error),
viewBinding.userNameInputLayout
)
}
"@event:邮箱占用" -> {
setErrorAndInput(
viewBinding.emailView,
getString(R.string.email_error2),
viewBinding.emailInputLayout
)
}
else -> {
Snackbar.make(
viewBinding.registerButton,
apiResponse.message,
Snackbar.LENGTH_SHORT
).show()
}
}
} else {
Snackbar.make(
viewBinding.registerButton,
apiResponse.message,
Snackbar.LENGTH_SHORT
).show()
}
}
}
override fun onFailure(e: Exception) {
isRegister = false
viewBinding.registerButton.setBackgroundColor(
GlobalMethod.getColorPrimary(
this@RegisterActivity
)
)
viewBinding.registerButton.setText(R.string.register)
showInternetError(viewBinding.registerButton, e)
}
})
}
})
}
/**
* 检查邮箱
* @param email String
* @return Boolean
*/
fun checkEmail(email: String, updateView: Boolean = true): Boolean {
return if (email.isBlank()) {
if (updateView) {
setErrorAndInput(
viewBinding.emailView,
String.format(
getString(R.string.please_input_value),
viewBinding.emailInputLayout.hint.toString()
), viewBinding.emailInputLayout
)
}
false
} else {
if (email.matches(Regex("^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*\$"))) {
if (updateView) {
viewBinding.emailInputLayout.isErrorEnabled = false
}
true
} else {
if (updateView) {
setErrorAndInput(
viewBinding.emailView,
getString(R.string.email_error), viewBinding.emailInputLayout, false
)
}
false
}
}
}
/**
* 检查确认密码
* @param confirmPassword String
* @return Boolean
*/
fun checkConfirmPassword(confirmPassword: String, updateView: Boolean = true): Boolean {
return if (confirmPassword.isBlank()) {
if (updateView) {
setErrorAndInput(
viewBinding.confirmPasswordView, String.format(
getString(R.string.please_input_value),
viewBinding.confirmPasswordInputLayout.hint.toString()
), viewBinding.confirmPasswordInputLayout
)
}
false
} else {
val passWord = viewBinding.passwordView.text.toString()
if (passWord == confirmPassword) {
if (updateView) {
viewBinding.confirmPasswordInputLayout.isErrorEnabled = false
}
true
} else {
if (updateView) {
setErrorAndInput(
viewBinding.confirmPasswordView,
getString(R.string.confirm_password_error),
viewBinding.confirmPasswordInputLayout,
false
)
}
false
}
}
}
/**
* 检查密码
* @param passWord String
* @return Boolean
*/
fun checkPassword(passWord: String, updateView: Boolean = true): Boolean {
return if (passWord.isBlank()) {
if (updateView) {
setErrorAndInput(
viewBinding.passwordView,
getString(R.string.please_enter_your_password),
viewBinding.passwordInputLayout
)
}
false
} else {
if (passWord.matches(Regex("^[a-zA-Z0-9_]{6,20}\$"))) {
if (updateView) {
viewBinding.passwordInputLayout.isErrorEnabled = false
}
true
} else {
if (updateView) {
setErrorAndInput(
viewBinding.passwordView,
getString(R.string.password_error),
viewBinding.passwordInputLayout, false
)
}
false
}
}
}
/**
* 检查用户名
* @param userName String
* @return Boolean
*/
fun checkUserName(userName: String, updateView: Boolean = true): Boolean {
return if (userName.isBlank()) {
if (updateView) {
setErrorAndInput(
viewBinding.userNameView,
String.format(
getString(R.string.please_input_value),
viewBinding.userNameInputLayout.hint.toString()
),
viewBinding.userNameInputLayout
)
}
false
} else {
if (updateView) {
viewBinding.userNameInputLayout.isErrorEnabled = false
}
true
}
}
/**
* 检查账号是否合法
* @param account String
* @return Boolean
*/
fun checkAccount(account: String, updateView: Boolean = true): Boolean {
if (account.isBlank()) {
if (updateView) {
setErrorAndInput(
viewBinding.accountView,
getString(R.string.please_enter_your_account), viewBinding.accountInputLayout
)
}
return false
} else {
return if (account.matches(Regex("^[A-Za-z0-9_]+\$"))) {
if (updateView) {
viewBinding.accountInputLayout.isErrorEnabled = false
}
true
} else {
if (updateView) {
setErrorAndInput(
viewBinding.accountView,
getString(R.string.account_error), viewBinding.accountInputLayout, false
)
}
false
}
}
}
/**
* 设置注册按钮启用状态
*/
fun setRegisterButtonEnable() {
val account = viewBinding.accountView.text.toString()
val passWord = viewBinding.passwordView.text.toString()
val userName = viewBinding.userNameView.text.toString()
val email = viewBinding.emailView.text.toString()
val confirmPassword = viewBinding.confirmPasswordView.text.toString()
viewBinding.registerButton.isEnabled =
checkConfirmPassword(confirmPassword, false) && checkAccount(
account,
false
) && checkUserName(userName, false) && checkPassword(
passWord
) && checkEmail(email, false)
}
override fun getViewBindingObject(layoutInflater: LayoutInflater): ActivityRegisterBinding {
return ActivityRegisterBinding.inflate(layoutInflater)
}
override fun whenCreateActivity(savedInstanceState: Bundle?, canUseView: Boolean) {
if (canUseView) {
title = getString(R.string.register)
setReturnButton()
initAction()
}
}
}

View File

@ -1,202 +0,0 @@
package com.coldmint.rust.pro
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.LayoutInflater
import android.widget.ArrayAdapter
import com.coldmint.rust.core.dataBean.ApiResponse
import com.coldmint.rust.core.interfaces.ApiCallBack
import com.coldmint.rust.core.web.Report
import com.coldmint.rust.core.web.ServerConfiguration
import com.coldmint.rust.pro.base.BaseActivity
import com.coldmint.rust.pro.databinding.ActivityReportBinding
import com.coldmint.rust.pro.tool.AppSettings
import com.coldmint.rust.pro.tool.GlobalMethod
import com.google.android.material.snackbar.Snackbar
/**
* 举报活动
* @author Cold Mint
* @date 2022/1/6 15:38
*/
class ReportActivity : BaseActivity<ActivityReportBinding>() {
lateinit var type: String
lateinit var target: String
override fun getViewBindingObject(layoutInflater: LayoutInflater): ActivityReportBinding {
return ActivityReportBinding.inflate(layoutInflater)
}
override fun whenCreateActivity(savedInstanceState: Bundle?, canUseView: Boolean) {
if (canUseView) {
title = getText(R.string.report)
setReturnButton()
val bundle = intent.getBundleExtra("data")
if (bundle == null) {
showError("无效的启动方式")
return
}
val temType = bundle.getString("type")
if (temType == null) {
showError("请设置启动类型")
return
}
if (temType != "mod" && temType != "user") {
showError("type只能是mod或user")
return
}
type = temType
val temTarget = bundle.getString("target")
if (temTarget == null) {
showError("请输入目标")
return
}
val name = bundle.getString("name")
if (name == null) {
showError("请输入名称")
return
}
val account = AppSettings.getValue(AppSettings.Setting.Account, "")
if (account.isBlank()) {
showError(getString(R.string.please_login_first))
return
}
val newTitle = String.format(getString(R.string.report_t), name)
viewBinding.toolbar.title = newTitle
target = temTarget
viewBinding.describeEdit.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(
s: CharSequence?,
start: Int,
count: Int,
after: Int
) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
override fun afterTextChanged(s: Editable?) {
val describe = s.toString()
checkDescribe(describe)
enableButton()
}
})
viewBinding.whyEditText.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(
s: CharSequence?,
start: Int,
count: Int,
after: Int
) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
override fun afterTextChanged(s: Editable?) {
val describe = s.toString()
checkWhy(describe)
enableButton()
}
})
viewBinding.reportButton.setOnClickListener {
val actionType = viewBinding.reportButton.text.toString()
if (actionType == getString(R.string.submit)) {
val describe = viewBinding.describeEdit.text.toString()
if (checkDescribe(describe)) {
inputMethodManager.hideSoftInputFromWindow(it.windowToken, 0)
viewBinding.reportButton.setText(R.string.request_data)
Report.instance.send(
account,
type,
target,
viewBinding.whyEditText.text.toString(),
describe,
object : ApiCallBack<ApiResponse> {
override fun onResponse(t: ApiResponse) {
if (t.code == ServerConfiguration.Success_Code) {
viewBinding.reportButton.setText(R.string.submit_complete)
} else {
Snackbar.make(
viewBinding.reportButton,
t.message,
Snackbar.LENGTH_SHORT
).show()
viewBinding.reportButton.setText(R.string.submit_failure)
}
}
override fun onFailure(e: Exception) {
viewBinding.reportButton.setText(R.string.submit_failure)
showInternetError(viewBinding.reportButton, e)
}
}
)
}
}
}
}
}
fun enableButton() {
val why = checkWhy(viewBinding.whyEditText.text.toString(), false)
val describe = checkDescribe(viewBinding.describeEdit.text.toString(), false)
viewBinding.reportButton.isEnabled = why && describe
}
/**
* 检查描述
*/
fun checkDescribe(describe: String, updateUi: Boolean = true): Boolean {
return if (describe.isBlank()) {
if (updateUi) {
setErrorAndInput(
viewBinding.describeEdit,
getString(R.string.describe_error), viewBinding.describeInputLayout
)
}
false
} else {
if (updateUi) {
viewBinding.describeInputLayout.isErrorEnabled = false
}
true
}
}
/**
* 检查描述
*/
fun checkWhy(describe: String, updateUi: Boolean = true): Boolean {
return if (describe.isBlank()) {
if (updateUi) {
setErrorAndInput(
viewBinding.whyEditText,
String.format(
getString(R.string.please_input_value),
viewBinding.whyLayout.hint
), viewBinding.whyLayout
)
}
false
} else {
if (updateUi) {
viewBinding.whyLayout.isErrorEnabled = false
}
true
}
}
}

View File

@ -10,7 +10,6 @@ import android.widget.Toast
import androidx.appcompat.app.AppCompatDelegate
import androidx.preference.ListPreference
import androidx.preference.Preference
import androidx.preference.PreferenceCategory
import androidx.preference.PreferenceFragmentCompat
import com.bumptech.glide.Glide
import com.coldmint.rust.core.tool.FileOperator

View File

@ -122,12 +122,6 @@ class ModActionAdapter(
mContext.getString(R.string.rename) -> {
renameItem()
}
mContext.getString(R.string.release) -> {
releaseItem()
}
mContext.getString(R.string.work_of_home_page) -> {
openHomePage()
}
mContext.getString(R.string.global_operations) -> {
val intent = Intent(mContext, GlobalOperationsActivity::class.java)
intent.putExtra("modPath", mModpath)
@ -189,19 +183,6 @@ class ModActionAdapter(
}
/**
* 打开作品首页
*/
private fun openHomePage() {
}
/**
* 点击了发布
*/
private fun releaseItem() {
}
/**
* 点击了重命名
*/

View File

@ -2,47 +2,44 @@ package com.coldmint.rust.pro.fragments
import android.annotation.SuppressLint
import android.content.res.ColorStateList
import android.os.*
import android.os.Build
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.view.isVisible
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.lifecycle.lifecycleScope
import com.bumptech.glide.Glide
import com.coldmint.rust.core.ModClass
import com.coldmint.rust.core.dataBean.ModConfigurationData
import com.coldmint.rust.core.tool.DebugHelper
import com.coldmint.rust.core.tool.FileOperator
import com.coldmint.rust.pro.R
import com.coldmint.rust.pro.adapters.ModActionAdapter
import com.coldmint.rust.pro.adapters.ModAdapter
import com.coldmint.rust.pro.base.BaseFragment
import com.coldmint.rust.pro.databinding.ModDialogBinding
import com.coldmint.rust.pro.databinding.FragmentModBinding
import com.coldmint.rust.pro.databinding.ModDialogBinding
import com.coldmint.rust.pro.databinding.ModListItemBinding
import com.coldmint.rust.pro.tool.AppSettings
import com.coldmint.rust.pro.tool.GlobalMethod
import com.coldmint.rust.pro.tool.Tools
import com.coldmint.rust.pro.ui.StableLinearLayoutManager
import com.coldmint.rust.pro.viewmodel.ModViewModel
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.divider.MaterialDividerItemDecoration
import com.google.android.material.snackbar.Snackbar
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.isActive
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import me.zhanghai.android.fastscroll.FastScrollerBuilder
import java.io.File
class ModFragment : BaseFragment<FragmentModBinding>() {
val viewModel: ModViewModel by lazy {
private val viewModel: ModViewModel by lazy {
ModViewModel()
}
lateinit var modAdapter: ModAdapter
val needRecycling by lazy {
private lateinit var modAdapter: ModAdapter
private val needRecycling by lazy {
if (GlobalMethod.isActive) {
AppSettings.getValue(
AppSettings.Setting.EnableRecoveryStation,
@ -55,16 +52,13 @@ class ModFragment : BaseFragment<FragmentModBinding>() {
/**
* 删除文件
* @param handler Handler
* @param modClass ModClass
*/
fun delFile(
handler: Handler,
private fun delFile(
modClass: ModClass,
index: Int? = null
) {
val scope = CoroutineScope(Job())
scope.launch {
lifecycleScope.launch(Dispatchers.IO) {
val targetFile = modClass.modFile
val errorFolder =
File(AppSettings.dataRootDirectory + "/modErrorReport/" + modClass.modName)
@ -86,7 +80,7 @@ class ModFragment : BaseFragment<FragmentModBinding>() {
shmFile.delete()
walFile.delete()
if (needRecycling) {
var result = false
val result: Boolean
val removePath: String
val removeFile: File
if (targetFile.isDirectory) {
@ -108,7 +102,7 @@ class ModFragment : BaseFragment<FragmentModBinding>() {
if (removeFile.exists()) {
FileOperator.delete_files(removeFile)
}
handler.post {
withContext(Dispatchers.Main) {
Snackbar.make(
viewBinding.modList,
String.format(
@ -120,7 +114,7 @@ class ModFragment : BaseFragment<FragmentModBinding>() {
}
result = FileOperator.removeFiles(targetFile, removeFile)
if (result) {
handler.post {
withContext(Dispatchers.Main) {
Snackbar.make(
viewBinding.modList,
String.format(
@ -131,10 +125,13 @@ class ModFragment : BaseFragment<FragmentModBinding>() {
).show()
if (index != null) {
modAdapter.removeItem(index)
if (modAdapter.itemCount == 0) {
notFindMod()
}
}
}
} else {
handler.post {
withContext(Dispatchers.Main) {
Snackbar.make(
viewBinding.modList,
getString(R.string.cut_failed),
@ -143,7 +140,7 @@ class ModFragment : BaseFragment<FragmentModBinding>() {
}
}
} else {
handler.post {
withContext(Dispatchers.Main) {
Snackbar.make(
viewBinding.modList,
String.format(
@ -154,7 +151,7 @@ class ModFragment : BaseFragment<FragmentModBinding>() {
).show()
}
FileOperator.delete_files(targetFile)
handler.post {
withContext(Dispatchers.Main) {
Snackbar.make(
viewBinding.modList,
String.format(
@ -165,6 +162,9 @@ class ModFragment : BaseFragment<FragmentModBinding>() {
).show()
if (index != null) {
modAdapter.removeItem(index)
if (modAdapter.itemCount == 0) {
notFindMod()
}
}
}
}
@ -175,31 +175,24 @@ class ModFragment : BaseFragment<FragmentModBinding>() {
* 加载模组列表
*/
fun loadModList() {
val scope = CoroutineScope(Job())
val handler = Handler(Looper.getMainLooper())
scope.launch {
lifecycleScope.launch(Dispatchers.IO) {
val dataList = viewModel.loadMod()
handler.post {
withContext(Dispatchers.Main) {
viewBinding.progressBar.isVisible = true
viewBinding.modErrorIcon.isVisible = false
viewBinding.modError.isVisible = false
viewBinding.swipeRefreshLayout.isVisible = false
}
if (dataList == null) {
handler.post {
viewBinding.modError.setText(R.string.not_find_mod)
viewBinding.modError.isVisible = true
viewBinding.modErrorIcon.isVisible = true
viewBinding.swipeRefreshLayout.isVisible = false
viewBinding.progressBar.isVisible = false
if (dataList.isNullOrEmpty()) {
withContext(Dispatchers.Main) {
notFindMod()
}
} else {
handler.post {
withContext(Dispatchers.Main) {
viewBinding.swipeRefreshLayout.isVisible = true
viewBinding.progressBar.isVisible = false
viewBinding.modErrorIcon.isVisible = false
viewBinding.modError.isVisible = false
if (isAdded) {
modAdapter = ModAdapter(requireContext(), dataList)
FastScrollerBuilder(viewBinding.modList).useMd2Style()
.setPopupTextProvider(modAdapter).build()
@ -212,16 +205,16 @@ class ModFragment : BaseFragment<FragmentModBinding>() {
modClass.modName,
viewHolder.absoluteAdapterPosition,
onClickPositiveButton = { d, b ->
delFile(handler, modClass, viewHolder.absoluteAdapterPosition)
delFile(
modClass,
viewHolder.absoluteAdapterPosition
)
false
})
false
}
}
viewBinding.modList.adapter = modAdapter
} else {
DebugHelper.printLog("加载模组列表", "没有附加到活动", isError = true)
}
}
}
}
@ -240,8 +233,6 @@ class ModFragment : BaseFragment<FragmentModBinding>() {
ModDialogBinding.inflate(LayoutInflater.from(context))
val bottomSheetDialog =
BottomSheetDialog(context)
modDialogBinding.modNameView.text = viewBinding.modNameView.text
modDialogBinding.modNameDescription.text = viewBinding.modIntroductionView.text
val configurationManager = modClass.modConfigurationManager
@ -266,12 +257,6 @@ class ModFragment : BaseFragment<FragmentModBinding>() {
if (title.isNotEmpty()) {
works.add(title)
}
val modId = configurationData.modId
if (modId != null) {
works.add(0, getString(R.string.work_of_home_page))
}
}
} else {
works.add(getString(R.string.rename))
@ -317,7 +302,8 @@ class ModFragment : BaseFragment<FragmentModBinding>() {
)
}
bottomSheetDialog.setContentView(modDialogBinding.root)
val bottomSheet = bottomSheetDialog.findViewById<View>(com.google.android.material.R.id.design_bottom_sheet)
val bottomSheet =
bottomSheetDialog.findViewById<View>(com.google.android.material.R.id.design_bottom_sheet)
if (bottomSheet != null) {
val behavior = BottomSheetBehavior.from(bottomSheet)
behavior.state = BottomSheetBehavior.STATE_EXPANDED // 默认展开
@ -328,16 +314,16 @@ class ModFragment : BaseFragment<FragmentModBinding>() {
bottomSheetDialog.show()
}
// /**
// * 显示没有找到模组
// */
// fun showNotFindMod() {
// viewBinding.modError.setText(R.string.not_find_mod)
// viewBinding.modError.isVisible = true
// viewBinding.modErrorIcon.isVisible = true
// viewBinding.modList.isVisible = false
// viewBinding.progressBar.isVisible = false
// }
/**
* 显示没有找到模组
*/
private fun notFindMod() {
viewBinding.modError.setText(R.string.not_find_mod)
viewBinding.modError.isVisible = true
viewBinding.modErrorIcon.isVisible = true
viewBinding.swipeRefreshLayout.isVisible = false
viewBinding.progressBar.isVisible = false
}
override fun getViewBindingObject(layoutInflater: LayoutInflater): FragmentModBinding {
return FragmentModBinding.inflate(layoutInflater)

View File

@ -1,11 +1,8 @@
package com.coldmint.rust.pro.fragments
import android.Manifest
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.view.LayoutInflater
import androidx.annotation.RequiresApi
import com.coldmint.rust.pro.CreationWizardActivity
import com.coldmint.rust.pro.R
import com.coldmint.rust.pro.adapters.WarehouseAdapter
@ -13,8 +10,6 @@ import com.coldmint.rust.pro.base.BaseFragment
import com.coldmint.rust.pro.databinding.FragmentWarehouseBinding
import com.coldmint.rust.pro.tool.GlobalMethod
import com.google.android.material.tabs.TabLayoutMediator
import com.hjq.permissions.OnPermissionCallback
import com.hjq.permissions.XXPermissions
/**
@ -22,12 +17,7 @@ import com.hjq.permissions.XXPermissions
* @date 2022/1/5 10:18
*/
class WarehouseFragment : BaseFragment<FragmentWarehouseBinding>() {
@RequiresApi(Build.VERSION_CODES.R)
private fun loadTab() {
// 在需要申请权限的地方调用如下方法
GlobalMethod.requestStoragePermissions(requireActivity()) {
}
if (isAdded) {
TabLayoutMediator(viewBinding.tabLayout, viewBinding.pager) { tab, position ->
when (position) {
@ -41,21 +31,22 @@ class WarehouseFragment : BaseFragment<FragmentWarehouseBinding>() {
}
}.attach()
viewBinding.mainButton.setOnClickListener {
val intent = Intent(context, CreationWizardActivity::class.java)
intent.putExtra("type", "mod")
startActivity(intent)
startActivity(Intent(context, CreationWizardActivity::class.java))
}
}
}
override fun getViewBindingObject(layoutInflater: LayoutInflater): FragmentWarehouseBinding {
return FragmentWarehouseBinding.inflate(layoutInflater)
}
override fun getViewBindingObject(layoutInflater: LayoutInflater): FragmentWarehouseBinding =
FragmentWarehouseBinding.inflate(layoutInflater)
override fun whenViewCreated(inflater: LayoutInflater, savedInstanceState: Bundle?) {
viewBinding.pager.adapter = WarehouseAdapter(this)
//解决启动为仓库页面,点击社区,再返回仓库重复崩溃的问题
viewBinding.pager.isSaveEnabled = false
// 在需要申请权限的地方调用如下方法
GlobalMethod.requestStoragePermissions(requireActivity()) {
}
loadTab()
}

View File

@ -288,6 +288,7 @@ object GlobalMethod {
)
}
if (XXPermissions.isGranted(activity, list)) {
requestCompleted.invoke(true)
return
}
MaterialAlertDialogBuilder(activity).setTitle(R.string.permission_request_title)
@ -301,7 +302,6 @@ object GlobalMethod {
requestCompleted.invoke(allGranted)
}
}.setNegativeButton(R.string.dialog_cancel, null).setCancelable(false).show()
}

View File

@ -1,100 +0,0 @@
package com.coldmint.rust.pro.ui
import android.animation.Animator
import android.animation.AnimatorSet
import android.animation.ObjectAnimator
import android.annotation.SuppressLint
import android.content.Context
import android.util.AttributeSet
import android.view.animation.AccelerateDecelerateInterpolator
import androidx.core.animation.addListener
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
import com.google.android.material.bottomsheet.BottomSheetDragHandleView
import android.view.MotionEvent as MotionEvent1
class BottomSheet(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : BottomSheetDragHandleView(context) {
constructor(context: Context) : this(context, null)
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
private var initialX = 0f
private var lastTouchX = 0f
private var deltaX = 0f
private val maxXOffset = 50f // 最大偏移量
var isScaling = false
// 覆盖 onTouchEvent 方法以处理触摸事件
@SuppressLint("ClickableViewAccessibility")
override fun onTouchEvent(event: MotionEvent1?): Boolean {
event?.let {
when (it.action) {
MotionEvent1.ACTION_DOWN -> {
// 触摸开始时的逻辑
// 记录初始位置
initialX = translationX
lastTouchX = event.rawX
// 触摸开始时放大
if (!isScaling) {
animate().scaleX(1.2f).scaleY(1.2f)
.setDuration(200)
.setInterpolator(FastOutSlowInInterpolator())
.withLayer()
.start()
isScaling = true
}
}
MotionEvent1.ACTION_MOVE -> {
val dx = event.rawX - lastTouchX
val fl = initialX + dx
if (fl < maxXOffset && fl > -maxXOffset) {
translationX = fl
}
}
MotionEvent1.ACTION_UP, MotionEvent1.ACTION_CANCEL -> {
// 触摸结束时恢复大小和位置
val animatorSet = AnimatorSet()
// 恢复大小
val scaleAnimator = ObjectAnimator.ofFloat(this, "scaleX", 1f)
scaleAnimator.duration = 200
scaleAnimator.interpolator = AccelerateDecelerateInterpolator()
val scaleYAnimator = ObjectAnimator.ofFloat(this, "scaleY", 1f)
scaleYAnimator.duration = 200
scaleYAnimator.interpolator = AccelerateDecelerateInterpolator()
// 恢复到原始位置
val translationAnimator = ObjectAnimator.ofFloat(this, "translationX", 0f)
translationAnimator.duration = 200
translationAnimator.interpolator = AccelerateDecelerateInterpolator()
// 将所有动画添加到 AnimatorSet 中并启动
animatorSet.playTogether(scaleAnimator, scaleYAnimator, translationAnimator)
animatorSet.start()
animatorSet.addListener(object : Animator.AnimatorListener {
override fun onAnimationStart(animation: Animator) {}
override fun onAnimationEnd(animation: Animator) {
isScaling = false
translationX = 0f
}
override fun onAnimationCancel(animation: Animator) {}
override fun onAnimationRepeat(animation: Animator) {}
})
}
else -> {
// 其他事件处理
}
}
}
// 返回 true 表示事件已经被消费,返回 false 表示事件没有被消费
return true
}
}

View File

@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M18,2H6C4.9,2 4,2.9 4,4v16c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2V4C20,2.9 19.1,2 18,2zM18,20H6V4h5v7l2.5,-1.5L16,11V4h2V20zM13.62,13.5L17,18H7l2.38,-3.17L11,17L13.62,13.5z" />
</vector>

View File

@ -2,7 +2,6 @@
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:card_view="http://schemas.android.com/tools"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -46,27 +45,6 @@
style="@style/TextAppearance.Material3.BodyMedium"
android:text="@string/error_content" />
<!-- <com.google.android.material.textfield.TextInputLayout-->
<!-- android:id="@+id/inputLayout"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:layout_below="@id/subTitleView"-->
<!-- android:layout_marginTop="8dp"-->
<!-- app:counterEnabled="true"-->
<!-- app:counterMaxLength="1500">-->
<!-- <com.google.android.material.textfield.TextInputEditText-->
<!-- android:id="@+id/inputEditView"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:hint="@string/error_description"-->
<!-- android:imeOptions="actionDone"-->
<!-- android:inputType="textMultiLine"-->
<!-- android:maxLength="1500"-->
<!-- android:maxLines="5" />-->
<!-- </com.google.android.material.textfield.TextInputLayout>-->
<com.google.android.material.card.MaterialCardView
style="@style/Widget.Material3.CardView.Filled"
android:layout_width="match_parent"

View File

@ -36,7 +36,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:text="@string/import_effor7" />
android:text="@string/import_complete" />
<Button
android:id="@+id/okButton"

View File

@ -1,147 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="16dp"
android:layout_marginTop="8dp"
android:layout_marginRight="16dp"
android:gravity="center"
android:orientation="vertical">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/accountInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:counterEnabled="true"
app:counterMaxLength="20"
app:helperText="@string/account_tip">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/accountView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/account"
android:imeOptions="actionNext"
android:inputType="text"
android:maxLength="20"
android:maxLines="1" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/userNameInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
app:counterEnabled="true"
app:counterMaxLength="20">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/userNameView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/user_name"
android:imeOptions="actionNext"
android:inputType="text"
android:maxLength="20" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/passwordInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
app:counterEnabled="true"
app:counterMaxLength="20"
app:passwordToggleEnabled="true">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/passwordView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/password"
android:imeOptions="actionNext"
android:inputType="textPassword"
android:maxLength="20" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/confirmPasswordInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
app:counterEnabled="true"
app:counterMaxLength="20"
app:passwordToggleEnabled="true">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/confirmPasswordView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/confirm_password"
android:imeOptions="actionNext"
android:inputType="textPassword"
android:maxLength="20" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
style="@style/Widget.Material3.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:id="@+id/emailInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:counterEnabled="true"
app:counterMaxLength="30">
<com.google.android.material.textfield.MaterialAutoCompleteTextView
android:id="@+id/emailView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/email"
android:imeOptions="actionDone"
android:inputType="textEmailAddress"
android:maxLength="30"
android:maxLines="1" />
</com.google.android.material.textfield.TextInputLayout>
<Button
android:id="@+id/registerButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:enabled="false"
android:text="@string/register" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -1,87 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:card_view="http://schemas.android.com/tools"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".ActivateActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="16dp"
android:layout_marginTop="8dp"
android:layout_marginRight="16dp"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.textfield.TextInputLayout
android:hint="@string/why"
android:id="@+id/whyLayout"
style="@style/Widget.Material3.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.textfield.MaterialAutoCompleteTextView
android:layout_width="match_parent"
android:inputType="none"
android:id="@+id/whyEditText"
app:simpleItems="@array/report_entries"
android:layout_height="wrap_content" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/describeInputLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="8dp"
app:counterEnabled="true"
app:counterMaxLength="255">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/describeEdit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/describe"
android:imeOptions="actionNext"
android:minLines="3"
android:gravity="top"
android:inputType="textMultiLine"
android:maxLength="255"
android:maxLines="10" />
</com.google.android.material.textfield.TextInputLayout>
<Button
android:enabled="false"
android:layout_marginTop="16dp"
android:id="@+id/reportButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/submit" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -2,8 +2,8 @@
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:fitsSystemWindows="true"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
@ -17,12 +17,10 @@
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
android:background="@android:color/transparent"
android:layout_width="match_parent"
app:tabGravity="center"
app:tabMode="auto"
app:tabMaxWidth="300dp"
android:layout_height="wrap_content" />
android:layout_height="wrap_content"
android:background="@android:color/transparent"
app:tabTextAppearance="@style/TabLayoutTextStyle" />
</com.google.android.material.appbar.AppBarLayout>

View File

@ -4,20 +4,25 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent" />
android:background="@android:color/transparent"
app:tabTextAppearance="@style/TabLayoutTextStyle" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/mainButton"
android:layout_width="wrap_content"

View File

@ -5,10 +5,9 @@
android:orientation="vertical"
android:padding="8dp">
<com.coldmint.rust.pro.ui.BottomSheet
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"/>
<com.google.android.material.bottomsheet.BottomSheetDragHandleView
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="match_parent"

View File

@ -1,7 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/mod_linearlayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"

View File

@ -1,12 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:showAsAction="always"
android:id="@+id/photo_album_shortcut"
android:icon="@drawable/outline_photo_album_24"
android:title="@string/photo_album" />
<item
android:icon="@drawable/ic_outline_sort_24"
android:title="@string/soft"
app:showAsAction="always">
android:showAsAction="ifRoom"
android:title="@string/soft">
<menu>
<group android:checkableBehavior="single">
<item
android:id="@+id/action_sort_by_name"
@ -26,8 +30,8 @@
<item
android:id="@+id/action_bookmark"
android:icon="@drawable/ic_outline_bookmarks_24"
android:title="@string/bookmark_manager"
app:showAsAction="ifRoom">
android:showAsAction="ifRoom"
android:title="@string/bookmark_manager">
<menu>
<item
@ -49,14 +53,6 @@
<item
android:id="@+id/reloadFile"
android:title="@string/reload_files" />
<!--
<item
android:id="@+id/app_bar_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checkable="true"
android:checked="false"
android:title="隐藏文件" />-->
<item
android:id="@+id/selectFile"
android:title="@string/select_file">

View File

@ -129,7 +129,7 @@
<string name="copy_file_absolutely_path_error">复制绝对路径错误。</string>
<string name="create_folder">创建文件夹</string>
<string name="photo_album">相册</string>
<string name="system_file_manager">文件管理器</string>
<string name="system_file_manager">系统文件管理器</string>
<string name="reload_files">刷新</string>
<string name="convert_template">制作模板</string>
<string name="open_game_test">测试此单位</string>
@ -163,6 +163,7 @@
<!--导入-->
<string name="importing">导入中...</string>
<string name="import_name">导入</string>
<string name="import_tip">等待导入...</string>
<string name="import_complete">%1$s 导入成功。</string>
<string name="import_failed">%1$s 导入失败。</string>
<string name="app_version_error">%1$s 专为高版本助手开发,无法导入。</string>
@ -304,7 +305,7 @@
<string name="complete_settings">已完成设置</string>
<string name="edit">编辑</string>
<string name="restore_all">全部还原</string>
<string name="copyright" translatable="false">Copyright ©coldmint 2020-%1$d All Rights Reserved.</string>
<string name="copyright" translatable="false">Copyright ©Cold-Mint 2020-%1$d All Rights Reserved.</string>
<string name="about">关于</string>
<string name="additional_selection">附加项</string>
<string name="delete_source_file">打包完成后删除源文件</string>
@ -618,4 +619,6 @@
<string name="variable_name">变量名</string>
<string name="permission_request_title">请求权限</string>
<string name="permission_request_message">我们需要存储权限以访问您的模组。</string>
<string name="clear_recovery_station_message">清空回收站,被删除的文件将无法恢复。</string>
<string name="delete_confirm">删除后将无法恢复。</string>
</resources>