This commit is contained in:
coldmint 2022-08-17 09:25:20 +08:00
parent 23a43c98f5
commit 24d9faba32
73 changed files with 2504 additions and 1476 deletions

Binary file not shown.

View File

@ -88,12 +88,12 @@ dependencies {
// TinyPinyin核心包80KB
implementation 'com.github.promeg:tinypinyin:2.0.3'
implementation 'io.github.youth5201314:banner:2.2.2'
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.core:core-ktx:1.8.0'
implementation 'com.github.deano2390:MaterialShowcaseView:1.3.4'
implementation 'com.google.code.gson:gson:2.8.9'
implementation 'com.google.code.gson:gson:2.9.1'
implementation 'com.github.yalantis:ucrop:2.2.6-native'
implementation 'com.kongzue.stacklabel:stacklabelview:1.1.9'
implementation files('libs/editor_0.8.aar')
implementation 'io.github.Rosemoe.sora-editor:editor:0.16.5'
implementation project(path: ':assistantCoreLibrary')
implementation project(path: ':turretsDragView')
implementation project(path: ':dialog')

Binary file not shown.

View File

@ -261,8 +261,8 @@
android:screenOrientation="portrait" />
<activity
android:name=".EditActivity"
android:configChanges="orientation"
android:exported="true"
android:windowSoftInputMode="adjustResize"
android:label="@string/mod_action1"
android:screenOrientation="portrait" />
<activity

View File

@ -122,6 +122,7 @@ class CreateModActivity : BaseActivity<ActivityCreateModBinding>() {
val fileWriter = FileWriter(mod_directory.absolutePath + "/mod-info.txt")
fileWriter.write(stringBuilder.toString())
fileWriter.close()
setResult(RESULT_OK)
finish()
} catch (e: IOException) {
e.printStackTrace()

View File

@ -5,6 +5,7 @@ import android.os.Bundle
import android.content.Intent
import android.view.LayoutInflater
import android.widget.*
import androidx.activity.result.contract.ActivityResultContracts
import com.coldmint.rust.pro.adapters.CreateUnitPageAdapter
import com.coldmint.rust.pro.databinding.ActivityCreateUnitBinding
import com.google.android.material.tabs.TabLayoutMediator
@ -38,43 +39,29 @@ class CreateUnitActivity : BaseActivity<ActivityCreateUnitBinding>() {
}.attach()
val root = bundle.getString("modPath")
createUnitPageAdapter.setRootPath(root)
val set = createUnitPageAdapter.setCreatePath(bundle.getString("createPath", root))
// if (!set) {
// //如果没有设置成功当fragment没有附加到activity
// viewBinding.toolbar.postDelayed({
// createUnitPageAdapter.setCreatePath(bundle.getString("createPath", root))
// }, 50)
createUnitPageAdapter.setCreatePath(bundle.getString("createPath", root))
// registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
// val resultCode = it.resultCode
// when (requestCode) {
// 1 -> if (resultCode == RESULT_OK) {
// val directents = data!!.getStringExtra("Directents")
// if (directents != null) {
// createUnitPageAdapter.setCreatePath(directents)
// }
// loadlist()
}
}
// fun getmCreatePath(): String {
// return mCreatePath
// }
// 2 -> if (resultCode == RESULT_OK) {
// val path = data!!.getStringExtra("File")
// val intent = Intent()
// intent.putExtra("File", path)
// setResult(RESULT_OK, intent)
// finish()
// }
// }
// }
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
1 -> if (resultCode == RESULT_OK) {
val directents = data!!.getStringExtra("Directents")
if (directents != null) {
createUnitPageAdapter.setCreatePath(directents)
}
}
2 -> if (resultCode == RESULT_OK) {
val path = data!!.getStringExtra("File")
val intent = Intent()
intent.putExtra("File", path)
setResult(RESULT_OK, intent)
finish()
}
}
}
override fun getViewBindingObject(layoutInflater: LayoutInflater): ActivityCreateUnitBinding {
return ActivityCreateUnitBinding.inflate(layoutInflater)
}

View File

@ -3,7 +3,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.pro.adapters.GuideAdapter
@ -13,11 +16,22 @@ import com.coldmint.rust.pro.databinding.ActivityCreationWizardBinding
import com.coldmint.rust.pro.tool.AppSettings
class CreationWizardActivity : BaseActivity<ActivityCreationWizardBinding>() {
lateinit var createMod: ActivityResultLauncher<Intent>
//创建向导类型(模组,模板包)
lateinit var type: String
override fun whenCreateActivity(savedInstanceState: Bundle?, canUseView: Boolean) {
setReturnButton()
title = getString(R.string.creation_assistant)
createMod = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
if (it.resultCode == RESULT_OK) {
finish()
Log.d("创建单位", "收到了数据,关闭界面。")
} else {
Log.d("创建单位", "没有收到数据。")
}
}
val temType = intent.getStringExtra("type")
if (temType.isNullOrBlank()) {
showToast("请传入类型")
@ -74,7 +88,7 @@ class CreationWizardActivity : BaseActivity<ActivityCreationWizardBinding>() {
val fileBundle = Bundle()
fileBundle.putString("type", "selectFile")
startIntent.putExtra("data", fileBundle)
startActivity(startIntent )
startActivity(startIntent)
}
}
}
@ -118,15 +132,14 @@ class CreationWizardActivity : BaseActivity<ActivityCreationWizardBinding>() {
val adapter = GuideAdapter(this, dataList)
adapter.setItemEvent { i, itemGuideBinding, viewHolder, guideData ->
itemGuideBinding.root.setOnClickListener {
finish()
when (guideData.titleRes) {
R.string.create_mod_lable -> {
startActivity(
val startActivity =
Intent(
this,
CreateModActivity::class.java
)
)
createMod.launch(startActivity)
}
R.string.import_mod -> {
val startIntent =
@ -135,6 +148,7 @@ class CreationWizardActivity : BaseActivity<ActivityCreationWizardBinding>() {
fileBundle.putString("type", "selectFile")
startIntent.putExtra("data", fileBundle)
startActivity(startIntent)
finish()
}
R.string.import_mod_from_package_directory -> {
val startIntent =
@ -149,9 +163,11 @@ class CreationWizardActivity : BaseActivity<ActivityCreationWizardBinding>() {
fileBundle.putString("rootpath", packDirectory)
startIntent.putExtra("data", fileBundle)
startActivity(startIntent)
finish()
}
R.string.import_mod_from_recycle_bin -> {
startActivity(Intent(this, RecyclingStationActivity::class.java))
finish()
}
}
}

View File

@ -60,10 +60,10 @@ import com.flask.colorpicker.ColorPickerView
import com.flask.colorpicker.builder.ColorPickerDialogBuilder
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.snackbar.Snackbar
import io.github.rosemoe.sora.data.CompletionItem
import io.github.rosemoe.sora.lang.completion.CompletionItem
import io.github.rosemoe.sora.widget.schemes.EditorColorScheme
import java.io.File
import java.util.*
import io.github.rosemoe.sora.widget.EditorColorScheme
import kotlin.collections.ArrayList
@ -75,9 +75,6 @@ class EditActivity : BaseActivity<ActivityEditBinding>() {
private lateinit var rustLanguage: RustLanguage
private var fileAdapter: FileAdapter? = null
val symbolChannel by lazy {
viewBinding.codeEditor.createNewSymbolChannel()
}
//是第一次启动嘛
var isFirst = true
@ -199,41 +196,41 @@ class EditActivity : BaseActivity<ActivityEditBinding>() {
rustLanguage.setEnglish(it)
}
viewBinding.codeEditor.setItemListener { i, completionItem ->
viewModel.executorService.submit {
val extrasData = completionItem.extrasData
if (extrasData != null) {
val listData = extrasData.getString("list")
if (listData != null) {
val lineParser = LineParser(listData)
lineParser.symbol = ","
val list = ArrayList<CompletionItem>()
lineParser.analyse { lineNum, lineData, isEnd ->
val temCodeInfo =
CodeDataBase.getInstance(this).getCodeDao().findCodeByCode(lineData)
if (temCodeInfo == null) {
} else {
val completionItemConverter = CompletionItemConverter.instance
completionItemConverter.init(this)
list.add(
completionItemConverter.codeInfoToCompletionItem(
temCodeInfo
)
)
}
true
}
if (list.isNotEmpty()) {
runOnUiThread {
viewBinding.codeEditor.createEditorAutoCompleteList(list)
}
}
}
}
}
true
}
// viewBinding.codeEditor.setItemListener { i, completionItem ->
// viewModel.executorService.submit {
// val extrasData = completionItem.extrasData
// if (extrasData != null) {
// val listData = extrasData.getString("list")
// if (listData != null) {
// val lineParser = LineParser(listData)
// lineParser.symbol = ","
// val list = ArrayList<CompletionItem>()
// lineParser.analyse { lineNum, lineData, isEnd ->
// val temCodeInfo =
// CodeDataBase.getInstance(this).getCodeDao().findCodeByCode(lineData)
// if (temCodeInfo == null) {
//
// } else {
// val completionItemConverter = CompletionItemConverter.instance
// completionItemConverter.init(this)
// list.add(
// completionItemConverter.codeInfoToCompletionItem(
// temCodeInfo
// )
// )
// }
// true
// }
// if (list.isNotEmpty()) {
// runOnUiThread {
// viewBinding.codeEditor.createEditorAutoCompleteList(list)
// }
// }
// }
// }
// }
// true
// }
viewModel.openedSourceFileListLiveData.observe(this) {
viewBinding.tabLayout.removeAllTabs()
it.forEach {
@ -314,11 +311,11 @@ class EditActivity : BaseActivity<ActivityEditBinding>() {
}
viewModel.codeLiveData.observe(this) {
rustLanguage.autoCompleteProvider.setSourceFolder(
FileOperator.getSuperDirectory(
viewModel.getNowOpenFilePath()
)
)
// rustLanguage.autoCompleteProvider.setSourceFolder(
// FileOperator.getSuperDirectory(
// viewModel.getNowOpenFilePath()
// )
// )
//初始化加载路径数据(仅在第一次有效)
editStartViewModel.initLoadPathLiveData(viewModel.getNowOpenFilePath())
viewBinding.myProgressBar.isVisible = false
@ -480,8 +477,8 @@ class EditActivity : BaseActivity<ActivityEditBinding>() {
loadStartObserve()
loadEndObserve()
initDrawerLayout()
initCodeEditor()
initCodeToolbar()
initCodeEditor()
initStartView()
initEndView()
showRenewalTip()
@ -979,7 +976,7 @@ class EditActivity : BaseActivity<ActivityEditBinding>() {
builder.append(viewModel.convertDigital(r))
builder.append(viewModel.convertDigital(g))
builder.append(viewModel.convertDigital(b))
symbolChannel.insertSymbol(builder.toString(), builder.length)
viewBinding.codeEditor.insertText(builder.toString(), builder.length)
}
.setNegativeButton(R.string.dialog_cancel) { dialog, which -> }
.build()
@ -1000,107 +997,107 @@ class EditActivity : BaseActivity<ActivityEditBinding>() {
).show()
}
} else if (item == getString(R.string.code_tip)) {
viewModel.executorService.submit {
try {
val list = ArrayList<CompletionItem>()
//如果不包含:搜索键
val lineNumber = viewBinding.codeEditor.selectedLineNumber
val navigationList =
viewBinding.codeEditor.textAnalyzeResult.navigation
var section: String? = null
if (navigationList != null && navigationList.isNotEmpty()) {
for (navigation in navigationList) {
if (navigation.line > lineNumber) {
break
} else {
section = navigation.label
}
}
}
//如果不在任何节内
if (section == null) {
runOnUiThread {
runOnUiThread {
Snackbar.make(
viewBinding.recyclerview,
this.getString(R.string.code_tip_error1),
Snackbar.LENGTH_SHORT
).show()
}
}
return@submit
}
val trueSection =
rustLanguage.autoCompleteProvider.getSectionType(section)
val codeDataBase = CodeDataBase.getInstance(this)
val lineData =
viewBinding.codeEditor.text.getLine(lineNumber).toString()
if (lineData.startsWith('[') && lineData.endsWith(']')) {
runOnUiThread {
Snackbar.make(
viewBinding.recyclerview,
R.string.code_tip_error2,
Snackbar.LENGTH_SHORT
).show()
}
return@submit
}
val index = lineData.indexOf(':')
if (index > -1) {
//如果包含:
runOnUiThread {
Snackbar.make(
viewBinding.recyclerview,
this.getString(R.string.can_not_tip_value),
Snackbar.LENGTH_SHORT
).show()
}
return@submit
} else {
val codeInfoList = if (lineData.isBlank()) {
codeDataBase.getCodeDao().findCodeBySection(trueSection)
} else {
val number = AppSettings.getValue(
AppSettings.Setting.IdentifiersPromptNumber,
40
)
codeDataBase.getCodeDao()
.findCodeByKeyFromSection(lineData, trueSection, number)
}
if (codeInfoList != null && codeInfoList.isNotEmpty()) {
val completionItemConverter =
CompletionItemConverter.instance.init(this)
codeInfoList.forEach {
list.add(
completionItemConverter.codeInfoToCompletionItem(
it
)
)
}
} else {
runOnUiThread {
Snackbar.make(
viewBinding.recyclerview,
String.format(
this.getString(R.string.code_tip_error3),
SourceFile.getSectionType(section)
),
Snackbar.LENGTH_SHORT
).show()
}
}
}
runOnUiThread {
viewBinding.codeEditor.createEditorAutoCompleteList(list)
}
} catch (e: Exception) {
e.printStackTrace()
}
}
// viewModel.executorService.submit {
// try {
// val list = ArrayList<CompletionItem>()
// //如果不包含:搜索键
// val lineNumber = viewBinding.codeEditor.selectedLineNumber
// val navigationList =
// viewBinding.codeEditor.textAnalyzeResult.navigation
// var section: String? = null
// if (navigationList != null && navigationList.isNotEmpty()) {
// for (navigation in navigationList) {
// if (navigation.line > lineNumber) {
// break
// } else {
// section = navigation.label
// }
// }
// }
// //如果不在任何节内
// if (section == null) {
// runOnUiThread {
// runOnUiThread {
// Snackbar.make(
// viewBinding.recyclerview,
// this.getString(R.string.code_tip_error1),
// Snackbar.LENGTH_SHORT
// ).show()
// }
// }
// return@submit
// }
// val trueSection =
// rustLanguage.autoCompleteProvider.getSectionType(section)
// val codeDataBase = CodeDataBase.getInstance(this)
// val lineData =
// viewBinding.codeEditor.text.getLine(lineNumber).toString()
// if (lineData.startsWith('[') && lineData.endsWith(']')) {
// runOnUiThread {
// Snackbar.make(
// viewBinding.recyclerview,
// R.string.code_tip_error2,
// Snackbar.LENGTH_SHORT
// ).show()
// }
// return@submit
// }
// val offset = lineData.indexOf(':')
// if (offset > -1) {
// //如果包含:
// runOnUiThread {
// Snackbar.make(
// viewBinding.recyclerview,
// this.getString(R.string.can_not_tip_value),
// Snackbar.LENGTH_SHORT
// ).show()
// }
// return@submit
// } else {
// val codeInfoList = if (lineData.isBlank()) {
// codeDataBase.getCodeDao().findCodeBySection(trueSection)
// } else {
// val number = AppSettings.getValue(
// AppSettings.Setting.IdentifiersPromptNumber,
// 40
// )
// codeDataBase.getCodeDao()
// .findCodeByKeyFromSection(lineData, trueSection, number)
// }
// if (codeInfoList != null && codeInfoList.isNotEmpty()) {
// val completionItemConverter =
// CompletionItemConverter.instance.init(this)
// codeInfoList.forEach {
// list.add(
// completionItemConverter.codeInfoToCompletionItem(
// it
// )
// )
// }
// } else {
// runOnUiThread {
// Snackbar.make(
// viewBinding.recyclerview,
// String.format(
// this.getString(R.string.code_tip_error3),
// SourceFile.getSectionType(section)
// ),
// Snackbar.LENGTH_SHORT
// ).show()
// }
// }
// }
// runOnUiThread {
// viewBinding.codeEditor.createEditorAutoCompleteList(list)
// }
// } catch (e: Exception) {
// e.printStackTrace()
// }
//
// }
} else {
try {
symbolChannel.insertSymbol(item, item.length)
viewBinding.codeEditor.insertText(item, item.length)
} catch (e: Exception) {
e.printStackTrace()
}
@ -1139,53 +1136,41 @@ class EditActivity : BaseActivity<ActivityEditBinding>() {
rustLanguage.setCodeEditor(viewBinding.codeEditor)
val night = AppSettings.getValue(AppSettings.Setting.NightMode, false)
val editorColorScheme = EditorColorScheme()
if (night) {
val backgroundColor = GlobalMethod.getThemeColor(this, android.R.attr.windowBackground)
//代码(可识别的关键字)
editorColorScheme.setColor(EditorColorScheme.KEYWORD, Color.rgb(178, 119, 49))
editorColorScheme.setColor(
EditorColorScheme.KEYWORD,
GlobalMethod.getThemeColor(this, android.R.attr.colorSecondary)
)
//默认文本
editorColorScheme.setColor(EditorColorScheme.TEXT_NORMAL, Color.rgb(169, 183, 198))
//注释
editorColorScheme.setColor(EditorColorScheme.COMMENT, Color.rgb(128, 128, 128))
editorColorScheme.setColor(
EditorColorScheme.COMMENT,
GlobalMethod.getThemeColor(this, android.R.attr.textColorTertiary)
)
//节
editorColorScheme.setColor(
EditorColorScheme.FUNCTION_NAME,
Color.rgb(152, 118, 170)
GlobalMethod.getColorPrimary(this)
)
//错误
editorColorScheme.setColor(
EditorColorScheme.WHOLE_BACKGROUND,
Color.rgb(60, 63, 65)
backgroundColor
)
editorColorScheme.setColor(
EditorColorScheme.LINE_NUMBER_BACKGROUND,
Color.rgb(60, 63, 65)
backgroundColor
)
} else {
//代码(可识别的关键字)
editorColorScheme.setColor(EditorColorScheme.KEYWORD, Color.rgb(42, 92, 170))
//默认文本
editorColorScheme.setColor(EditorColorScheme.TEXT_NORMAL, Color.BLACK)
//注释
editorColorScheme.setColor(EditorColorScheme.COMMENT, Color.rgb(128, 128, 128))
//节
editorColorScheme.setColor(EditorColorScheme.FUNCTION_NAME, Color.rgb(170, 33, 22))
editorColorScheme.setColor(
EditorColorScheme.WHOLE_BACKGROUND,
Color.rgb(240, 240, 243)
)
//变量名
editorColorScheme.setColor(EditorColorScheme.LITERAL, Color.rgb(153, 50, 204))
}
viewBinding.codeEditor.colorScheme = editorColorScheme
viewBinding.codeEditor.setAutoCompletionItemAdapter(RustCompletionAdapter())
viewBinding.codeEditor.isVerticalScrollBarEnabled = false
val path = viewModel.modClass?.modFile?.absolutePath ?: ""
rustLanguage.autoCompleteProvider.setConfigurationFileConversion(
path,
"ROOT",
path
)
// rustLanguage.autoCompleteProvider.setConfigurationFileConversion(
// path,
// "ROOT",
// path
// )
viewBinding.codeEditor.setEditorLanguage(rustLanguage)
}
@ -1262,49 +1247,49 @@ class EditActivity : BaseActivity<ActivityEditBinding>() {
}
}
R.id.code_navigation -> {
viewModel.executorService.submit {
val labels = viewBinding.codeEditor.textAnalyzeResult.navigation
if (labels == null || labels.size == 0) {
runOnUiThread {
Snackbar.make(
viewBinding.recyclerview,
R.string.not_find_code_navigation,
Snackbar.LENGTH_SHORT
).show()
}
} else {
val items = ArrayList<CharSequence>()
var i = 0
while (i < labels.size) {
items.add(labels[i].label)
i++
}
val tip = String.format(getString(R.string.navigation_tip), items.size)
runOnUiThread {
MaterialDialog(this).show {
title(R.string.code_navigation).positiveButton(R.string.dialog_cancel)
.message(text = tip)
.listItems(
items = items,
waitForPositiveButton = false,
selection = object : ItemListener {
override fun invoke(
dialog: MaterialDialog,
index: Int,
text: CharSequence
) {
viewBinding.codeEditor.jumpToLine(
labels[index].line
)
viewBinding.codeEditor.moveSelectionEnd()
dialog.dismiss()
}
})
}
}
}
}
// viewModel.executorService.submit {
// val labels = viewBinding.codeEditor.textAnalyzeResult.navigation
// if (labels == null || labels.size == 0) {
// runOnUiThread {
// Snackbar.make(
// viewBinding.recyclerview,
// R.string.not_find_code_navigation,
// Snackbar.LENGTH_SHORT
// ).show()
// }
// } else {
// val items = ArrayList<CharSequence>()
// var i = 0
// while (i < labels.size) {
// items.add(labels[i].label)
// i++
// }
// val tip = String.format(getString(R.string.navigation_tip), items.size)
// runOnUiThread {
// MaterialDialog(this).show {
// title(R.string.code_navigation).positiveButton(R.string.dialog_cancel)
// .message(text = tip)
// .listItems(
// items = items,
// waitForPositiveButton = false,
// selection = object : ItemListener {
// override fun invoke(
// dialog: MaterialDialog,
// offset: Int,
// text: CharSequence
// ) {
// viewBinding.codeEditor.jumpToLine(
// labels[offset].line
// )
// viewBinding.codeEditor.moveSelectionEnd()
// dialog.dismiss()
// }
//
// })
// }
// }
// }
// }
}
R.id.save_text -> {
val openedSourceFile =
@ -1534,24 +1519,24 @@ class EditActivity : BaseActivity<ActivityEditBinding>() {
viewBinding.editDrawerlayout.closeDrawer(GravityCompat.END)
}
addAdditionalName -> {
val labels =
viewBinding.codeEditor.textAnalyzeResult.navigation
var num = 1
labels.forEach {
val type = SourceFile.getSectionType(
it.label.substring(
1,
it.label.length - 1
)
)
if (type == sectionName) {
num++
}
}
val name = "_" + num.toString()
viewBinding.codeEditor.setSelection(lineNum, columnNum)
symbolChannel.insertSymbol(name, name.length)
viewBinding.editDrawerlayout.closeDrawer(GravityCompat.END)
// val labels =
// viewBinding.codeEditor.textAnalyzeResult.navigation
// var num = 1
// labels.forEach {
// val type = SourceFile.getSectionType(
// it.label.substring(
// 1,
// it.label.length - 1
// )
// )
// if (type == sectionName) {
// num++
// }
// }
// val name = "_" + num.toString()
// viewBinding.codeEditor.setSelection(lineNum, columnNum)
// viewBinding.codeEditor.insertText(name, name.length)
// viewBinding.editDrawerlayout.closeDrawer(GravityCompat.END)
}
}
false

View File

@ -142,7 +142,7 @@ class FileManagerActivity : BaseActivity<ActivityFileBinding>() {
// )
// )
// MaterialDialog(this).title(R.string.open_type)
// .listItems(items = openList) { dialog, index, text ->
// .listItems(items = openList) { dialog, offset, text ->
// when (text) {
// getString(R.string.edit_template) -> {
// editTemplate(file)

View File

@ -59,23 +59,22 @@ class LibraryActivity : BaseActivity<ActivityLibraryBinding>() {
"Apache License 2.0"
)
)
// libInfoArrayList.add(
// LibInfo(
// "Kongzue StackLabel",
// "空祖家的堆叠标签以下碎念一开始起名字“StackLabel”没想太多结果被人吐槽Stack是整齐堆叠的意思...........好吧这是我的锅不过现在要改也来不及了,好用就行了...吧?",
// "https://github.com/kongzue/StackLabel",
// "Apache License 2.0"
// )
// )
libInfoArrayList.add(
LibInfo(
"Kongzue StackLabel",
"空祖家的堆叠标签以下碎念一开始起名字“StackLabel”没想太多结果被人吐槽Stack是整齐堆叠的意思...........好吧这是我的锅不过现在要改也来不及了,好用就行了...吧?",
"https://github.com/kongzue/StackLabel",
"Apache License 2.0"
)
)
val libInfo = LibInfo(
"sora-editor",
"A cool code editor library on Android with syntax-highlighting and auto-completion. (aka CodeEditor)",
"https://github.com/Rosemoe/sora-editor",
"LGPL 2.1"
)
libInfo.tip =
"铁锈助手使用sora-editor的魔改版本。\n\n由ColdMint魔改自Rose的sora-editor编辑框。\n\n在原基础上新增功能:\n-列表控制api用于实现连锁提示\n-自定义列表适配器(用于适配视图)\n\n目前修改版本为0.8由ColdMint维护。\n\n于2022-1-25日同步主项目。"
libInfoArrayList.add(libInfo)
)
libInfoArrayList.add(
LibInfo(
"ColorPicker",

View File

@ -5,6 +5,8 @@ import com.coldmint.rust.pro.base.BaseActivity
import org.json.JSONObject
import android.os.Bundle
import android.content.Intent
import android.text.Editable
import android.text.TextWatcher
import android.util.Log
import com.coldmint.rust.pro.tool.AppSettings
import org.json.JSONException
@ -28,14 +30,20 @@ import com.coldmint.rust.core.dataBean.IntroducingDataBean
import com.coldmint.rust.core.dataBean.ListParserDataBean
import com.coldmint.rust.core.dataBean.template.LocalTemplateFile
import com.coldmint.rust.core.dataBean.template.TemplatePackage
import com.coldmint.rust.core.dataBean.template.WebTemplateData
import com.coldmint.rust.core.interfaces.ApiCallBack
import com.coldmint.rust.core.interfaces.TemplateParser
import com.coldmint.rust.core.templateParser.InputParser
import com.coldmint.rust.core.templateParser.IntroducingParser
import com.coldmint.rust.core.templateParser.ListParser
import com.coldmint.rust.core.tool.FileOperator
import com.coldmint.rust.core.web.ServerConfiguration
import com.coldmint.rust.core.web.TemplatePhp
import com.coldmint.rust.pro.databinding.ActivityTemplateParserBinding
import com.coldmint.rust.pro.tool.UnitAutoCompleteHelper
import com.coldmint.rust.pro.viewmodel.TemplateParserViewModel
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.dialog.MaterialDialogs
import com.google.android.material.textfield.TextInputLayout
import com.google.gson.Gson
import java.io.File
@ -68,9 +76,8 @@ class TemplateParserActivity : BaseActivity<ActivityTemplateParserBinding>() {
if (code.isBlank()) {
code = getString(R.string.not_found_data2)
}
CoreDialog(this).setTitle(viewModel.getTemplateName(language)).setMessage(code)
.setPositiveButton(R.string.dialog_ok) {
MaterialAlertDialogBuilder(this).setTitle(viewModel.getTemplateName(language))
.setMessage(code).setPositiveButton(R.string.dialog_ok) { i, i2 ->
}.show()
}
}
@ -79,8 +86,51 @@ class TemplateParserActivity : BaseActivity<ActivityTemplateParserBinding>() {
override fun whenCreateActivity(savedInstanceState: Bundle?, canUseView: Boolean) {
if (canUseView) {
setReturnButton()
val unitAutoCompleteHelper = UnitAutoCompleteHelper(this)
unitAutoCompleteHelper.onBindAutoCompleteTextView(viewBinding.fileNameInputView)
viewBinding.fileNameInputView.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 text = p0.toString()
if (text.isBlank()) {
viewBinding.fileNameInputLayout.error = getString(R.string.file_name_error)
} else {
viewBinding.fileNameInputLayout.isErrorEnabled = false
}
}
})
viewBinding.fab.setOnClickListener {
val name = viewBinding.fileNameInputView.text.toString()
if (name.isNotBlank()) {
val build = viewModel.buildFile(this, name)
if (build) {
setResult(RESULT_OK)
finish()
} else {
Snackbar.make(
viewBinding.fab,
R.string.create_unit_failed,
Snackbar.LENGTH_SHORT
).show()
}
}
}
val createDirectory = intent.getStringExtra("createDirectory")
if (createDirectory == null) {
Toast.makeText(this, "没有设置创建目录", Toast.LENGTH_SHORT).show()
finish()
return
}
viewModel.setCreateDirectory(createDirectory)
val link = intent.getStringExtra("link")
if (link == null) {
Toast.makeText(this, "请设置链接", Toast.LENGTH_SHORT).show()
@ -99,8 +149,42 @@ class TemplateParserActivity : BaseActivity<ActivityTemplateParserBinding>() {
viewBinding.nestedScrollView.isVisible = true
title = viewModel.getTemplateName(language)
} else {
Log.d("模板解析器", "加载网络模板$link")
TemplatePhp.instance.getTemplate(link, object : ApiCallBack<WebTemplateData> {
override fun onResponse(t: WebTemplateData) {
if (t.code == ServerConfiguration.Success_Code) {
viewModel.setTemplate(t.data)
val templateParserList =
viewModel.getTemplateParserList(this@TemplateParserActivity)
templateParserList.forEach {
viewBinding.base.addView(it.contextView)
}
viewBinding.linearLayout.isVisible = false
viewBinding.nestedScrollView.isVisible = true
title = viewModel.getTemplateName(language)
} else {
Toast.makeText(
this@TemplateParserActivity,
t.message,
Toast.LENGTH_SHORT
).show()
finish()
}
}
override fun onFailure(e: Exception) {
e.printStackTrace()
Toast.makeText(
this@TemplateParserActivity,
R.string.network_error,
Toast.LENGTH_SHORT
).show()
finish()
}
})
}
}
}

View File

@ -184,7 +184,8 @@ class UserHomePageActivity : BaseActivity<ActivityUserHomePageBinding>() {
viewBinding.loginTimeView.text = String.format(
getString(R.string.user_info),
spaceInfoData.data.loginTime,
spaceInfoData.data.account
spaceInfoData.data.account,
spaceInfoData.data.location
)
viewBinding.fab.isVisible = true

View File

@ -451,7 +451,7 @@ class ModActionAdapter(
if (string.isNotEmpty() && string != oldname) {
val newFile = File(FileOperator.getSuperDirectory(mod_file) + "/" + string)
mod_file.renameTo(newFile)
mModFragment.loadMods()
mModFragment.loadModList()
}
true
}.setNegativeButton(R.string.dialog_cancel) {
@ -728,7 +728,7 @@ class ModActionAdapter(
if (ok) {
handler.post {
materialDialog.dismiss()
mModFragment.loadMods()
mModFragment.loadModList()
Snackbar.make(
(mModFragment.view)!!,
R.string.repair_complete,
@ -764,7 +764,7 @@ class ModActionAdapter(
)
handler.post {
materialDialog.dismiss()
mModFragment.loadMods()
mModFragment.loadModList()
if (needShowSnackbar) {
Snackbar.make(
(mModFragment.view)!!,
@ -889,7 +889,7 @@ class ModActionAdapter(
repairThread.setModpath(unzip_path.absolutePath)
repairThread.start()
}
mModFragment.loadMods()
mModFragment.loadModList()
}
} else {
handler.post {

View File

@ -11,16 +11,17 @@ import com.bumptech.glide.Glide
import android.os.Build
import com.coldmint.rust.pro.base.BaseAdapter
import com.coldmint.rust.pro.databinding.ModListItemBinding
import me.zhanghai.android.fastscroll.PopupTextProvider
/*模组适配器
* 此适配器只能使用于ModFragment成员变量按需传递
* */
class ModAdapter(context: Context, dataList: MutableList<ModClass>) :
BaseAdapter<ModListItemBinding, ModClass>(context, dataList) {
BaseAdapter<ModListItemBinding, ModClass>(context, dataList), PopupTextProvider {
init {
dataList.sortBy {
it.modName
getInitial(it.modName)
}
}
@ -71,4 +72,9 @@ class ModAdapter(context: Context, dataList: MutableList<ModClass>) :
viewBinding.modUpTime.text = data.lastModificationTime
viewBinding.modNameView.text = data.modName
}
override fun getPopupText(position: Int): String {
val s = dataList[position].modName
return getInitial(s).toString()
}
}

View File

@ -13,8 +13,12 @@ import android.graphics.BitmapFactory
import android.content.Intent
import com.coldmint.rust.pro.TemplateParserActivity
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.ImageView
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.fragment.app.Fragment
import com.bumptech.glide.Glide
import com.coldmint.rust.core.LocalTemplatePackage
import com.coldmint.rust.core.dataBean.template.Template
@ -28,7 +32,8 @@ class TemplateAdapter(
private val context: Context,
private val mGroup: List<TemplatePackage>,
private val mItemList: List<List<Template>>,
mEnvironmentLanguage: String
mEnvironmentLanguage: String,
private val startTemplateParserActivity: ActivityResultLauncher<Intent>
) : BaseExpandableListAdapter() {
private val layoutInflater: LayoutInflater = LayoutInflater.from(context)
private val mEnvironmentLanguage: String
@ -117,7 +122,9 @@ class TemplateAdapter(
val intent = Intent(context, TemplateParserActivity::class.java)
intent.putExtra("link", templateClass.getLink())
intent.putExtra("isLocal", templateClass.isLocal())
context.startActivity(intent)
intent.putExtra("createDirectory", createPath)
startTemplateParserActivity.launch(intent)
}
return templateItemBinding.root
}

View File

@ -340,14 +340,14 @@ class TemplateListAdapter(
// holder.templateListItemBinding.delButton.setBackgroundColor(R.color.blue_200)
// holder.templateListItemBinding.delButton.setText(R.string.del_moding)
// }
// val index = mFiles.indexOf(templateClass.directest)
// mFiles.removeAt(index)
// val offset = mFiles.indexOf(templateClass.directest)
// mFiles.removeAt(offset)
// FileOperator.delete_files(templateClass.directest)
// mfragment.requireActivity().runOnUiThread {
// if (mFiles.size == 0) {
// mfragment.load_list(mRootPath, true)
// } else {
// notifyItemRemoved(index)
// notifyItemRemoved(offset)
// }
// }
// }.start()

View File

@ -3,7 +3,7 @@ package com.coldmint.rust.pro.adapters
import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import com.coldmint.rust.core.dataBean.webTemplate.WebTemplatePackageListData
import com.coldmint.rust.core.dataBean.WebTemplatePackageListData
import com.coldmint.rust.pro.R
import com.coldmint.rust.pro.base.BaseAdapter
import com.coldmint.rust.pro.databinding.ItemWebTemplateBinding

View File

@ -9,22 +9,19 @@ import com.coldmint.rust.core.interfaces.EnglishMode
import com.coldmint.rust.core.tool.LineParser
import com.coldmint.rust.core.tool.LocalVariableName
import com.coldmint.rust.pro.R
import io.github.rosemoe.sora.data.NavigationItem
import io.github.rosemoe.sora.data.Span
import io.github.rosemoe.sora.interfaces.CodeAnalyzer
import io.github.rosemoe.sora.text.TextAnalyzeResult
import io.github.rosemoe.sora.text.TextAnalyzer
import io.github.rosemoe.sora.widget.EditorColorScheme
import io.github.rosemoe.sora.lang.styling.Span
import io.github.rosemoe.sora.widget.schemes.EditorColorScheme
import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.HashMap
import kotlin.collections.HashSet
import kotlin.text.StringBuilder
class RustAnalyzer() : CodeAnalyzer,EnglishMode {
private val labels: ArrayList<NavigationItem> by lazy {
ArrayList()
}
@Deprecated("已过时")
class RustAnalyzer() : EnglishMode {
// private val labels: ArrayList<NavigationItem> by lazy {
// ArrayList()
// }
companion object {
/**
@ -57,292 +54,292 @@ class RustAnalyzer() : CodeAnalyzer,EnglishMode {
* @param colors TextAnalyzeResult
* @param delegate Delegate
*/
override fun analyze(
content: CharSequence,
colors: TextAnalyzeResult,
delegate: TextAnalyzer.AnalyzeThread.Delegate
) {
//添加换行符作为结束符
val str = content.toString() + "\n"
if (str.isBlank() || codeDataBase == null) {
return
}
val lineParser = LineParser()
lineParser.parserSymbol = true
lineParser.symbol = "_"
colors.addNormalIfNull()
if (delegate.shouldAnalyze()) {
labels.clear()
localVariableNameList.clear()
var codeBlockType: CompileConfiguration.CodeBlockType =
CompileConfiguration.CodeBlockType.Key
var lineNum = 0
val keyBuilder = StringBuilder()
val valueBuilder = StringBuilder()
var column = 0
var startIndex = -1
//是否执行二次渲染,用于判断值是否合法
var lineRendering = true
var lastSection: String? = null
val stringTokenizer = StringTokenizer(str, CodeCompiler2.split, true)
while (stringTokenizer.hasMoreTokens()) {
val code = stringTokenizer.nextToken()
when (code) {
"\n" -> {
if (codeBlockType != CompileConfiguration.CodeBlockType.Note && codeBlockType != CompileConfiguration.CodeBlockType.Section && lineRendering) {
renderLineContent(
startIndex,
lastSection,
colors,
lineNum,
keyBuilder,
valueBuilder
)
}
lineNum++
column = 0
lineRendering = true
startIndex = -1
codeBlockType = CompileConfiguration.CodeBlockType.Key
keyBuilder.clear()
valueBuilder.clear()
}
" ", ",", "/" -> if (codeBlockType != CompileConfiguration.CodeBlockType.Note) {
if (codeBlockType == CompileConfiguration.CodeBlockType.Value) {
valueBuilder.append(code)
}
column += code.length
}
":" -> {
if (lastSection != null && codeBlockType != CompileConfiguration.CodeBlockType.Note) {
codeBlockType = CompileConfiguration.CodeBlockType.Value
colors.addIfNeeded(lineNum, column, EditorColorScheme.TEXT_NORMAL)
column += code.length
}
}
"\r" -> {
}
"(", ")", "=", "%", "." -> if (codeBlockType != CompileConfiguration.CodeBlockType.Note) {
if (codeBlockType == CompileConfiguration.CodeBlockType.Value || codeBlockType == CompileConfiguration.CodeBlockType.VariableName) {
valueBuilder.append(code)
}
column += code.length
}
"}" -> {
if (codeBlockType != CompileConfiguration.CodeBlockType.Note) {
if (codeBlockType == CompileConfiguration.CodeBlockType.VariableName) {
colors.addIfNeeded(
lineNum,
column,
EditorColorScheme.TEXT_NORMAL
)
codeBlockType = CompileConfiguration.CodeBlockType.Value
valueBuilder.append(code)
}
column += code.length
}
}
"{" -> {
if (codeBlockType != CompileConfiguration.CodeBlockType.Note) {
if (codeBlockType == CompileConfiguration.CodeBlockType.Value) {
lineRendering = false
codeBlockType = CompileConfiguration.CodeBlockType.VariableName
valueBuilder.append(code)
}
column += code.length
}
}
else -> if (codeBlockType != CompileConfiguration.CodeBlockType.Note) {
if (codeBlockType == CompileConfiguration.CodeBlockType.VariableName) {
val symbol = "."
val symbolIndex = code.indexOf(symbol)
if (symbolIndex > -1) {
//渲染 ${节.键} 的格式
val sectionSpan =
Span.obtain(column, EditorColorScheme.FUNCTION_NAME)
colors.add(
lineNum,
sectionSpan
)
val symbolSpan =
Span.obtain(
column + symbolIndex,
EditorColorScheme.TEXT_NORMAL
)
colors.add(
lineNum,
symbolSpan
)
val keySpan = Span.obtain(
column + symbolIndex + symbol.length,
EditorColorScheme.KEYWORD
)
colors.add(lineNum, keySpan)
// override fun analyze(
// content: CharSequence,
// colors: TextAnalyzeResult,
// delegate: TextAnalyzer.AnalyzeThread.Delegate
// ) {
// //添加换行符作为结束符
// val str = content.toString() + "\n"
// if (str.isBlank() || codeDataBase == null) {
// return
// }
// val lineParser = LineParser()
// lineParser.parserSymbol = true
// lineParser.symbol = "_"
// colors.addNormalIfNull()
// if (delegate.shouldAnalyze()) {
// labels.clear()
// localVariableNameList.clear()
// var codeBlockType: CompileConfiguration.CodeBlockType =
// CompileConfiguration.CodeBlockType.Key
// var lineNum = 0
// val keyBuilder = StringBuilder()
// val valueBuilder = StringBuilder()
// var column = 0
// var startIndex = -1
// //是否执行二次渲染,用于判断值是否合法
// var lineRendering = true
// var lastSection: String? = null
// val stringTokenizer = StringTokenizer(str, CodeCompiler2.split, true)
// while (stringTokenizer.hasMoreTokens()) {
// val code = stringTokenizer.nextToken()
// when (code) {
// "\n" -> {
// if (codeBlockType != CompileConfiguration.CodeBlockType.Note && codeBlockType != CompileConfiguration.CodeBlockType.Section && lineRendering) {
// renderLineContent(
// startIndex,
// lastSection,
// colors,
// lineNum,
// keyBuilder,
// valueBuilder
// )
// }
// lineNum++
// column = 0
// lineRendering = true
// startIndex = -1
// codeBlockType = CompileConfiguration.CodeBlockType.Key
// keyBuilder.clear()
// valueBuilder.clear()
// }
// " ", ",", "/" -> if (codeBlockType != CompileConfiguration.CodeBlockType.Note) {
// if (codeBlockType == CompileConfiguration.CodeBlockType.Value) {
// valueBuilder.append(code)
// }
// column += code.length
// }
// ":" -> {
// if (lastSection != null && codeBlockType != CompileConfiguration.CodeBlockType.Note) {
// codeBlockType = CompileConfiguration.CodeBlockType.Value
// colors.addIfNeeded(lineNum, column, EditorColorScheme.TEXT_NORMAL)
// column += code.length
// }
// }
// "\r" -> {
// }
// "(", ")", "=", "%", "." -> if (codeBlockType != CompileConfiguration.CodeBlockType.Note) {
// if (codeBlockType == CompileConfiguration.CodeBlockType.Value || codeBlockType == CompileConfiguration.CodeBlockType.VariableName) {
// valueBuilder.append(code)
// }
// column += code.length
// }
// "}" -> {
// if (codeBlockType != CompileConfiguration.CodeBlockType.Note) {
// if (codeBlockType == CompileConfiguration.CodeBlockType.VariableName) {
// colors.addIfNeeded(
// lineNum,
// column,
// EditorColorScheme.TEXT_NORMAL
// )
// codeBlockType = CompileConfiguration.CodeBlockType.Value
// valueBuilder.append(code)
// }
// column += code.length
// }
// }
// "{" -> {
// if (codeBlockType != CompileConfiguration.CodeBlockType.Note) {
// if (codeBlockType == CompileConfiguration.CodeBlockType.Value) {
// lineRendering = false
// codeBlockType = CompileConfiguration.CodeBlockType.VariableName
// valueBuilder.append(code)
// }
// column += code.length
// }
// }
// else -> if (codeBlockType != CompileConfiguration.CodeBlockType.Note) {
// if (codeBlockType == CompileConfiguration.CodeBlockType.VariableName) {
// val symbol = "."
// val symbolIndex = code.indexOf(symbol)
// if (symbolIndex > -1) {
// //渲染 ${节.键} 的格式
// val sectionSpan =
// Span.obtain(column, EditorColorScheme.FUNCTION_NAME)
// colors.add(
// lineNum,
// sectionSpan
// )
// val symbolSpan =
// Span.obtain(
// column + symbolIndex,
// EditorColorScheme.TEXT_NORMAL
// )
// colors.add(
// lineNum,
// symbolSpan
// )
// val keySpan = Span.obtain(
// column + symbolIndex + symbol.length,
// EditorColorScheme.KEYWORD
// )
// colors.add(lineNum, keySpan)
//
// } else {
// //渲染 ${变量名} 的个格式
// localVariableNameList.add(LocalVariableName(code, lineNum))
// val span = Span.obtain(column, EditorColorScheme.LITERAL)
// colors.add(
// lineNum,
// span
// )
// }
// } else {
// //不是变量名的话
// if (code.startsWith("#")) {
// codeBlockType = CompileConfiguration.CodeBlockType.Note
// colors.addIfNeeded(lineNum, column, EditorColorScheme.COMMENT)
// } else if (code.startsWith("[") && code.endsWith("]")) {
// codeBlockType = CompileConfiguration.CodeBlockType.Section
// lastSection = code
// labels.add(
// NavigationItem(
// lineNum,
// code.substring(1, code.length - 1)
// )
// )
// val span = Span.obtain(0, EditorColorScheme.FUNCTION_NAME)
// colors.add(
// lineNum,
// span
// )
// } else {
// if (lastSection != null) {
// //当代码属于某个节时渲染
// if (codeBlockType == CompileConfiguration.CodeBlockType.Key) {
// keyBuilder.append(code)
// if (hasCode(code)) {
// colors.addIfNeeded(
// lineNum,
// column,
// EditorColorScheme.KEYWORD
// )
// val trueCode = getCode(code)
// if (trueCode == "@define" || trueCode == "@global") {
// codeBlockType =
// CompileConfiguration.CodeBlockType.VariableName
// }
// } else {
// if (code.contains("_")) {
// val parser = LineParser(code)
// parser.symbol = "_"
// parser.parserSymbol = true
// //局部渲染偏移
// var offset = 0
// parser.analyse { temLineNum, lineData, isEnd ->
// if (lineData == parser.symbol) {
// //是符号,添加符号跨度
// colors.addIfNeeded(
// lineNum, column + offset,
// EditorColorScheme.TEXT_NORMAL
// )
// } else {
// if (hasCode(lineData)) {
// colors.addIfNeeded(
// lineNum,
// column + offset,
// EditorColorScheme.KEYWORD
// )
// } else {
// colors.addIfNeeded(
// lineNum, column + offset,
// EditorColorScheme.TEXT_NORMAL
// )
// }
// }
// offset += lineData.length
// true
// }
// } else {
// val span =
// Span.obtain(
// column,
// EditorColorScheme.TEXT_NORMAL
// )
// colors.add(
// lineNum,
// span
// )
// }
// }
// } else {
// if (startIndex == -1) {
// startIndex = column
// }
// valueBuilder.append(getCode(code))
// }
// }
// }
// }
// column += code.length
// }
// }
// }
// colors.navigation = labels
// colors.determine(lineNum)
// }
// }
} else {
//渲染 ${变量名} 的个格式
localVariableNameList.add(LocalVariableName(code, lineNum))
val span = Span.obtain(column, EditorColorScheme.LITERAL)
colors.add(
lineNum,
span
)
}
} else {
//不是变量名的话
if (code.startsWith("#")) {
codeBlockType = CompileConfiguration.CodeBlockType.Note
colors.addIfNeeded(lineNum, column, EditorColorScheme.COMMENT)
} else if (code.startsWith("[") && code.endsWith("]")) {
codeBlockType = CompileConfiguration.CodeBlockType.Section
lastSection = code
labels.add(
NavigationItem(
lineNum,
code.substring(1, code.length - 1)
)
)
val span = Span.obtain(0, EditorColorScheme.FUNCTION_NAME)
colors.add(
lineNum,
span
)
} else {
if (lastSection != null) {
//当代码属于某个节时渲染
if (codeBlockType == CompileConfiguration.CodeBlockType.Key) {
keyBuilder.append(code)
if (hasCode(code)) {
colors.addIfNeeded(
lineNum,
column,
EditorColorScheme.KEYWORD
)
val trueCode = getCode(code)
if (trueCode == "@define" || trueCode == "@global") {
codeBlockType =
CompileConfiguration.CodeBlockType.VariableName
}
} else {
if (code.contains("_")) {
val parser = LineParser(code)
parser.symbol = "_"
parser.parserSymbol = true
//局部渲染偏移
var offset = 0
parser.analyse { temLineNum, lineData, isEnd ->
if (lineData == parser.symbol) {
//是符号,添加符号跨度
colors.addIfNeeded(
lineNum, column + offset,
EditorColorScheme.TEXT_NORMAL
)
} else {
if (hasCode(lineData)) {
colors.addIfNeeded(
lineNum,
column + offset,
EditorColorScheme.KEYWORD
)
} else {
colors.addIfNeeded(
lineNum, column + offset,
EditorColorScheme.TEXT_NORMAL
)
}
}
offset += lineData.length
true
}
} else {
val span =
Span.obtain(
column,
EditorColorScheme.TEXT_NORMAL
)
colors.add(
lineNum,
span
)
}
}
} else {
if (startIndex == -1) {
startIndex = column
}
valueBuilder.append(getCode(code))
}
}
}
}
column += code.length
}
}
}
colors.navigation = labels
colors.determine(lineNum)
}
}
/**
* 渲染行内容
* @param startIndex Int 冒号的起初位置
* @param lastSection String? 最后的节
* @param colors TextAnalyzeResult 颜色渲染
* @param lineNum Int 行号
* @param keyBuilder StringBuilder
* @param valueBuilder StringBuilder
*/
private fun renderLineContent(
startIndex: Int,
lastSection: String?,
colors: TextAnalyzeResult,
lineNum: Int,
keyBuilder: StringBuilder,
valueBuilder: StringBuilder
) {
//不在任何节内
if (lastSection == null) {
val valueErrorSpan =
Span.obtain(
0,
EditorColorScheme.FUNCTION_NAME
)
valueErrorSpan.problemFlags = Span.FLAG_ERROR
colors.add(lineNum, valueErrorSpan)
return
}
if (startIndex > -1) {
//值是否合法
if (isValid(
keyBuilder.toString(),
valueBuilder.toString().trim()
)
) {
if (hasCode(valueBuilder.toString().trim(), true)) {
colors.addIfNeeded(
lineNum,
startIndex,
EditorColorScheme.KEYWORD
)
} else {
colors.addIfNeeded(
lineNum,
startIndex,
EditorColorScheme.TEXT_NORMAL
)
}
} else {
val valueErrorSpan =
Span.obtain(
startIndex,
EditorColorScheme.FUNCTION_NAME
)
valueErrorSpan.problemFlags = Span.FLAG_ERROR
colors.add(lineNum, valueErrorSpan)
}
}
}
// /**
// * 渲染行内容
// * @param startIndex Int 冒号的起初位置
// * @param lastSection String? 最后的节
// * @param colors TextAnalyzeResult 颜色渲染
// * @param lineNum Int 行号
// * @param keyBuilder StringBuilder
// * @param valueBuilder StringBuilder
// */
// private fun renderLineContent(
// startIndex: Int,
// lastSection: String?,
// colors: TextAnalyzeResult,
// lineNum: Int,
// keyBuilder: StringBuilder,
// valueBuilder: StringBuilder
// ) {
// //不在任何节内
// if (lastSection == null) {
// val valueErrorSpan =
// Span.obtain(
// 0,
// EditorColorScheme.FUNCTION_NAME
// )
// valueErrorSpan.problemFlags = Span.FLAG_ERROR
// colors.add(lineNum, valueErrorSpan)
// return
// }
// if (startIndex > -1) {
// //值是否合法
// if (isValid(
// keyBuilder.toString(),
// valueBuilder.toString().trim()
// )
// ) {
// if (hasCode(valueBuilder.toString().trim(), true)) {
// colors.addIfNeeded(
// lineNum,
// startIndex,
// EditorColorScheme.KEYWORD
// )
// } else {
// colors.addIfNeeded(
// lineNum,
// startIndex,
// EditorColorScheme.TEXT_NORMAL
// )
// }
// } else {
// val valueErrorSpan =
// Span.obtain(
// startIndex,
// EditorColorScheme.FUNCTION_NAME
// )
// valueErrorSpan.problemFlags = Span.FLAG_ERROR
// colors.add(lineNum, valueErrorSpan)
// }
// }
// }
/**

View File

@ -0,0 +1,433 @@
package com.coldmint.rust.pro.edit
import android.content.Context
import android.util.Log
import com.coldmint.rust.core.CodeCompiler2
import com.coldmint.rust.core.SourceFile
import com.coldmint.rust.core.database.code.CodeDataBase
import com.coldmint.rust.core.database.code.SectionInfo
import com.coldmint.rust.core.database.file.FileDataBase
import com.coldmint.rust.core.interfaces.EnglishMode
import com.coldmint.rust.core.tool.DebugHelper
import com.coldmint.rust.core.tool.LineParser
import com.coldmint.rust.pro.tool.AppSettings
import com.coldmint.rust.pro.tool.CompletionItemConverter
import io.github.rosemoe.sora.lang.completion.CompletionItem
import io.github.rosemoe.sora.lang.completion.CompletionPublisher
import io.github.rosemoe.sora.widget.CodeEditor
import java.util.ArrayList
import java.util.concurrent.Executors
/**
* @author Cold Mint
* @date 2022/1/25 17:32
*/
class RustAutoComplete(val context: Context) : EnglishMode {
private val debugKey = "自动完成器"
private var codeDataBase: CodeDataBase? = null
private val executorService = Executors.newCachedThreadPool()
private var fileDataBase: FileDataBase? = null
private var codeEditor: CodeEditor? = null
private var sectionNameMap: HashMap<String, String> = HashMap()
private val lineParser by lazy {
val tem = LineParser()
tem.symbol = ","
tem
}
private val identifiersPromptNumber: Int by lazy {
AppSettings.getValue(AppSettings.Setting.IdentifiersPromptNumber, 40)
}
//类型转换器
private val completionItemConverter: CompletionItemConverter by lazy {
CompletionItemConverter.instance.init(context)
}
companion object {
var keyWord = ""
}
/**
* 是否为英文模式
*/
private var isEnglishMode = false
/**
* 设置源文件目录
* @param sourceFolder String
*/
fun setSourceFolder(sourceFolder: String) {
DebugHelper.printLog(debugKey, "已设置源文件目录" + sourceFolder, "设置源文件目录")
completionItemConverter.setSourceFilePath(sourceFolder)
}
/**
* 设置文件转换器配置
* @param sourceFilePath String
* @param rootCodeName String
* @param modFolder String
*/
fun setConfigurationFileConversion(
sourceFilePath: String,
rootCodeName: String,
modFolder: String
) {
completionItemConverter.configurationFileConversion(sourceFilePath, rootCodeName, modFolder)
}
/**
*设置文件数据库
* @param fileDataBase FileDataBase?
*/
fun setFileDataBase(fileDataBase: FileDataBase?) {
this.fileDataBase = fileDataBase
}
fun setCodeDataBase(codeDataBase: CodeDataBase) {
this.codeDataBase = codeDataBase
}
/**
* 设置代码编辑器
* @param codeEditor CodeEditor?
*/
fun setCodeEditor(codeEditor: CodeEditor?) {
this.codeEditor = codeEditor
}
/**
* 获取节类型(永远返回英文)
* @param section String
* @return String
*/
fun getSectionType(section: String): String {
if (sectionNameMap.containsKey(section)) {
return sectionNameMap[section] ?: SourceFile.getSectionType(section)
}
val result = if (isEnglishMode) {
SourceFile.getSectionType(section)
} else {
val sectionInfo = codeDataBase!!.getSectionDao()
.findSectionInfoByTranslate(SourceFile.getSectionType(section))
sectionInfo?.code ?: SourceFile.getSectionType(section)
}
sectionNameMap[section] = result
return result
}
/**
* 请求自动完成
* @param prefix String?
* @param completionPublisher CompletionPublisher
* @param line Int
* @param column Int
*/
fun requireAutoComplete(
prefix: String?,
completionPublisher: CompletionPublisher,
line: Int,
column: Int
) {
if (codeEditor == null) {
throw NullPointerException("未绑定编辑框")
}
if (fileDataBase == null) {
throw NullPointerException("未绑定文件数据库")
}
if (codeDataBase == null) {
throw NullPointerException("未绑定代码数据库")
}
if (prefix == null) {
return
}
keyWord = prefix
val temCodeEditor: CodeEditor = codeEditor!!
val lineData = temCodeEditor.text.getLineString(line)
if (lineData.startsWith('[')) {
//搜索节
val name = lineData.subSequence(1, lineData.length).toString()
val list = if (isEnglishMode) {
codeDataBase!!.getSectionDao()
.searchSectionInfoByCode(name, limitNum = identifiersPromptNumber)
} else {
codeDataBase!!.getSectionDao()
.searchSectionInfoByTranslate(name, limitNum = identifiersPromptNumber)
}
list?.forEach {
completionPublisher.addItem(completionItemConverter.sectionInfoToCompletionItem(it))
}
} else {
val key = ":"
val keyIndex = lineData.lastIndexOf(key)
if (keyIndex > -1) {
//检查是否可响应变量
val start = "\${"
val end = "}"
val startIndex = lineData.lastIndexOf(start)
if (startIndex > -1) {
val endIndex = lineData.lastIndexOf(end)
if (endIndex < startIndex) {
//如果}的位置小于${的位置,说明没有闭合
val keyWord =
lineData.subSequence(startIndex + start.length, lineData.length)
.toString()
val previousText =
lineData.subSequence(keyIndex + key.length, startIndex).toString()
if (keyWord.isNotBlank()) {
RustAnalyzer.localVariableNameList.forEach {
if (it.name.contains(keyWord)) {
completionPublisher.addItem(
completionItemConverter.localVariableNameToCompletionItem(
it, previousText
)
)
}
}
} else {
RustAnalyzer.localVariableNameList.forEach {
completionPublisher.addItem(
completionItemConverter.localVariableNameToCompletionItem(
it, previousText
)
)
}
}
RustAutoComplete.keyWord = keyWord
return
}
}
// val value =
// lineData.subSequence(keyIndex + key.length, lineData.length).toString().trim()
// Log.d("值", value)
//搜索值
// frontIndex 前面冒号的位置
val frontIndex = lineData.lastIndexOf(key, keyIndex - key.length)
val keyValue = if (frontIndex > -1) {
lineData.subSequence(frontIndex + key.length, keyIndex)
} else {
lineData.subSequence(0, keyIndex)
}
val codeInfo =
if (isEnglishMode) {
codeDataBase!!.getCodeDao().findCodeByCode(keyValue.toString())
} else {
codeDataBase!!.getCodeDao().findCodeByTranslate(keyValue.toString())
}
DebugHelper.printLog(
debugKey,
"值[" + keyValue + "]英文模式[" + isEnglishMode + "]代码信息[" + codeInfo + "]关键字[" + prefix + "]",
"值检查"
)
if (codeInfo != null) {
val typeInfo = completionItemConverter.getValueType(codeInfo.type)
//获取代码的关联列表
if (typeInfo != null && typeInfo.list.isNotBlank()) {
DebugHelper.printLog(
debugKey,
"值类型[" + codeInfo.type + "]自动提示列表[" + typeInfo.list + "]", "关联提示"
)
lineParser.text = typeInfo.list
lineParser.analyse { lineNum, lineData, isEnd ->
//分析关联提示项目
val temCodeInfo =
codeDataBase!!.getCodeDao().findCodeByCode(lineData)
DebugHelper.printLog(
debugKey,
"值类型[" + codeInfo.type + "]项目[" + lineData + "]是代码[" + (temCodeInfo != null) + "]",
"关联提示列表分析"
)
if (temCodeInfo == null) {
if (lineData.startsWith("@file(") && lineData.endsWith(")")) {
val fileType = lineData.subSequence(
lineData.indexOf('(') + 1,
lineData.indexOf(')')
)
val fileInfo = fileDataBase!!.getFileInfoDao()
.searchFileInfoByNameAndType(
prefix,
fileType.toString(),
identifiersPromptNumber
)
DebugHelper.printLog(
debugKey,
"值类型[" + codeInfo.type + "]项目[" + lineData + "]搜索了[" + fileType + "]类型的文件,返回了[" + (fileInfo?.size
?: -1) + "]个结果",
"关联提示列表分析"
)
if (fileInfo != null && fileInfo.isNotEmpty()) {
for (fileTable in fileInfo) {
completionPublisher.addItem(
completionItemConverter.fileTableToCompletionItem(
fileTable
)
)
}
}
} else if (lineData.startsWith("@customType(") && lineData.endsWith(
")"
)
) {
//用户自动值类型提示
val customType = lineData.subSequence(
lineData.indexOf('(') + 1,
lineData.indexOf(')')
).toString()
fileDataBase!!.getValueDao()
.searchValueByKey(
prefix,
customType,
identifiersPromptNumber
)
?.forEach {
completionPublisher.addItem(
completionItemConverter.valueTableToCompletionItem(
it
)
)
}
} else if (lineData.startsWith("@type(") && lineData.endsWith(")")) {
val type = lineData.subSequence(
lineData.indexOf('(') + 1,
lineData.indexOf(')')
).toString()
val list = if (isEnglishMode
) {
codeDataBase!!.getCodeDao().findCodeByCodeInType(
prefix,
type,
identifiersPromptNumber
)
} else {
codeDataBase!!.getCodeDao().findCodeByTranslateInType(
prefix,
type,
identifiersPromptNumber
)
}
DebugHelper.printLog(
debugKey,
"关联了值类型[" + type + "]获取[" + (list?.size ?: -1) + "]个结果",
"值类型引用"
)
if (!list.isNullOrEmpty()) {
list.forEach {
completionPublisher.addItem(
completionItemConverter.codeInfoToCompletionItem(
it
)
)
}
}
} else if (lineData.startsWith("@section") && lineData.endsWith(
")"
)
) {
val section = lineData.subSequence(
lineData.indexOf('(') + 1,
lineData.indexOf(')')
).toString()
// codeEditor!!.textAnalyzeResult.navigation.forEach {
// if (section == getSectionType(it.label)) {
// result.add(
// completionItemConverter.navigationItemToCompletionItem(
// it
// )
// )
// }
// }
} else {
//无法分析的关联项目
// result.add(
// CompletionItem(
// lineData,
// String.format(
// completionItemConverter.associatedTip,
// codeInfo.translate
// )
// )
// )
}
} else {
val show = if (isEnglishMode) {
temCodeInfo.code.contains(prefix)
} else {
temCodeInfo.translate.contains(prefix)
}
DebugHelper.printLog(
debugKey,
"值类型[" + codeInfo.type + "]项目[" + lineData + "]是否包含" + prefix + "关键字[" + show + "]",
"关联提示列表分析"
)
if (show) {
completionPublisher.addItem(
completionItemConverter.codeInfoToCompletionItem(
temCodeInfo
)
)
}
}
true
}
}
}
} else {
//如果不包含:搜索键
// val navigationList = temCodeEditor.textAnalyzeResult.navigation
// var section: String? = null
// if (navigationList != null && navigationList.isNotEmpty()) {
// for (navigation in navigationList) {
// if (navigation.line > line) {
// break
// } else {
// section = navigation.label
// }
// }
// }
// //如果不在任何节内
// if (section == null) {
// return@submit
// }
// val trueSection = getSectionType(section)
// val list = if (isEnglishMode) {
// codeDataBase!!.getCodeDao().findCodeByEnglishCodeKeyFromSection(
// prefix,
// trueSection,
// identifiersPromptNumber
// )
// } else {
// codeDataBase!!.getCodeDao()
// .findCodeByKeyFromSection(prefix, trueSection, identifiersPromptNumber)
// }
// if (list != null && list.isNotEmpty()) {
// list.forEach {
// result.add(
// completionItemConverter.codeInfoToCompletionItem(it)
// )
// }
// }
}
}
}
override fun isEnglishMode(): Boolean {
return isEnglishMode
}
override fun setEnglish(englishMode: Boolean) {
this.isEnglishMode = englishMode
completionItemConverter.setEnglish(englishMode)
}
}

View File

@ -1,439 +0,0 @@
package com.coldmint.rust.pro.edit
import android.content.Context
import android.util.Log
import com.coldmint.rust.core.CodeCompiler2
import com.coldmint.rust.core.SourceFile
import com.coldmint.rust.core.database.code.CodeDataBase
import com.coldmint.rust.core.database.code.SectionInfo
import com.coldmint.rust.core.database.file.FileDataBase
import com.coldmint.rust.core.interfaces.EnglishMode
import com.coldmint.rust.core.tool.DebugHelper
import com.coldmint.rust.core.tool.LineParser
import com.coldmint.rust.pro.tool.AppSettings
import com.coldmint.rust.pro.tool.CompletionItemConverter
import io.github.rosemoe.sora.data.CompletionItem
import io.github.rosemoe.sora.interfaces.AutoCompleteProvider
import io.github.rosemoe.sora.text.TextAnalyzeResult
import io.github.rosemoe.sora.widget.CodeEditor
import java.util.ArrayList
import java.util.concurrent.Executors
/**
* @author Cold Mint
* @date 2022/1/25 17:32
*/
class RustAutoComplete2(val context: Context) : AutoCompleteProvider, EnglishMode {
private val result: ArrayList<CompletionItem> by lazy {
ArrayList()
}
private val debugKey = "自动完成器"
private var codeDataBase: CodeDataBase? = null
private val executorService = Executors.newCachedThreadPool()
private var fileDataBase: FileDataBase? = null
private var codeEditor: CodeEditor? = null
private var sectionNameMap: HashMap<String, String> = HashMap()
private val lineParser by lazy {
val tem = LineParser()
tem.symbol = ","
tem
}
private val identifiersPromptNumber: Int by lazy {
AppSettings.getValue(AppSettings.Setting.IdentifiersPromptNumber, 40)
}
//类型转换器
private val completionItemConverter: CompletionItemConverter by lazy {
CompletionItemConverter.instance.init(context)
}
companion object {
var keyWord = ""
}
/**
* 是否为英文模式
*/
private var isEnglishMode = false
/**
* 设置源文件目录
* @param sourceFolder String
*/
fun setSourceFolder(sourceFolder: String) {
DebugHelper.printLog(debugKey, "已设置源文件目录" + sourceFolder, "设置源文件目录")
completionItemConverter.setSourceFilePath(sourceFolder)
}
/**
* 设置文件转换器配置
* @param sourceFilePath String
* @param rootCodeName String
* @param modFolder String
*/
fun setConfigurationFileConversion(
sourceFilePath: String,
rootCodeName: String,
modFolder: String
) {
completionItemConverter.configurationFileConversion(sourceFilePath, rootCodeName, modFolder)
}
/**
*设置文件数据库
* @param fileDataBase FileDataBase?
*/
fun setFileDataBase(fileDataBase: FileDataBase?) {
this.fileDataBase = fileDataBase
}
fun setCodeDataBase(codeDataBase: CodeDataBase) {
this.codeDataBase = codeDataBase
}
/**
* 设置代码编辑器
* @param codeEditor CodeEditor?
*/
fun setCodeEditor(codeEditor: CodeEditor?) {
this.codeEditor = codeEditor
}
/**
* 获取节类型(永远返回英文)
* @param section String
* @return String
*/
fun getSectionType(section: String): String {
if (sectionNameMap.containsKey(section)) {
return sectionNameMap[section] ?: SourceFile.getSectionType(section)
}
val result = if (isEnglishMode) {
SourceFile.getSectionType(section)
} else {
val sectionInfo = codeDataBase!!.getSectionDao()
.findSectionInfoByTranslate(SourceFile.getSectionType(section))
sectionInfo?.code ?: SourceFile.getSectionType(section)
}
sectionNameMap[section] = result
return result
}
override fun getAutoCompleteItems(
prefix: String?,
analyzeResult: TextAnalyzeResult?,
line: Int,
column: Int
): MutableList<CompletionItem> {
if (codeEditor == null) {
throw NullPointerException("未绑定编辑框")
return ArrayList<CompletionItem>()
}
if (fileDataBase == null) {
throw NullPointerException("未绑定文件数据库")
return ArrayList<CompletionItem>()
}
if (codeDataBase == null) {
throw NullPointerException("未绑定代码数据库")
return ArrayList<CompletionItem>()
}
if (prefix == null) {
return ArrayList<CompletionItem>()
}
keyWord = prefix
val future = executorService.submit {
result.clear()
val temCodeEditor: CodeEditor = codeEditor!!
val lineData = temCodeEditor.text.getLineString(line)
if (lineData.startsWith('[')) {
//搜索节
val name = lineData.subSequence(1, lineData.length).toString()
val list = if (isEnglishMode) {
codeDataBase!!.getSectionDao()
.searchSectionInfoByCode(name, limitNum = identifiersPromptNumber)
} else {
codeDataBase!!.getSectionDao()
.searchSectionInfoByTranslate(name, limitNum = identifiersPromptNumber)
}
list?.forEach {
result.add(completionItemConverter.sectionInfoToCompletionItem(it))
}
} else {
val key = ":"
val keyIndex = lineData.lastIndexOf(key)
if (keyIndex > -1) {
//检查是否可响应变量
val start = "\${"
val end = "}"
val startIndex = lineData.lastIndexOf(start)
if (startIndex > -1) {
val endIndex = lineData.lastIndexOf(end)
if (endIndex < startIndex) {
//如果}的位置小于${的位置,说明没有闭合
val keyWord =
lineData.subSequence(startIndex + start.length, lineData.length)
.toString()
val previousText =
lineData.subSequence(keyIndex + key.length, startIndex).toString()
if (keyWord.isNotBlank()) {
RustAnalyzer.localVariableNameList.forEach {
if (it.name.contains(keyWord)) {
result.add(
completionItemConverter.localVariableNameToCompletionItem(
it, previousText
)
)
}
}
} else {
RustAnalyzer.localVariableNameList.forEach {
result.add(
completionItemConverter.localVariableNameToCompletionItem(
it, previousText
)
)
}
}
RustAutoComplete2.keyWord = keyWord
return@submit
}
}
// val value =
// lineData.subSequence(keyIndex + key.length, lineData.length).toString().trim()
// Log.d("值", value)
//搜索值
// frontIndex 前面冒号的位置
val frontIndex = lineData.lastIndexOf(key, keyIndex - key.length)
val keyValue = if (frontIndex > -1) {
lineData.subSequence(frontIndex + key.length, keyIndex)
} else {
lineData.subSequence(0, keyIndex)
}
val codeInfo =
if (isEnglishMode) {
codeDataBase!!.getCodeDao().findCodeByCode(keyValue.toString())
} else {
codeDataBase!!.getCodeDao().findCodeByTranslate(keyValue.toString())
}
DebugHelper.printLog(
debugKey,
"值[" + keyValue + "]英文模式[" + isEnglishMode + "]代码信息[" + codeInfo + "]关键字[" + prefix + "]",
"值检查"
)
if (codeInfo != null) {
val typeInfo = completionItemConverter.getValueType(codeInfo.type)
//获取代码的关联列表
if (typeInfo != null && typeInfo.list.isNotBlank()) {
DebugHelper.printLog(
debugKey,
"值类型[" + codeInfo.type + "]自动提示列表[" + typeInfo.list + "]", "关联提示"
)
lineParser.text = typeInfo.list
lineParser.analyse { lineNum, lineData, isEnd ->
//分析关联提示项目
val temCodeInfo =
codeDataBase!!.getCodeDao().findCodeByCode(lineData)
DebugHelper.printLog(
debugKey,
"值类型[" + codeInfo.type + "]项目[" + lineData + "]是代码[" + (temCodeInfo != null) + "]",
"关联提示列表分析"
)
if (temCodeInfo == null) {
if (lineData.startsWith("@file(") && lineData.endsWith(")")) {
val fileType = lineData.subSequence(
lineData.indexOf('(') + 1,
lineData.indexOf(')')
)
val fileInfo = fileDataBase!!.getFileInfoDao()
.searchFileInfoByNameAndType(
prefix,
fileType.toString(),
identifiersPromptNumber
)
DebugHelper.printLog(
debugKey,
"值类型[" + codeInfo.type + "]项目[" + lineData + "]搜索了[" + fileType + "]类型的文件,返回了[" + (fileInfo?.size
?: -1) + "]个结果",
"关联提示列表分析"
)
if (fileInfo != null && fileInfo.isNotEmpty()) {
for (fileTable in fileInfo) {
result.add(
completionItemConverter.fileTableToCompletionItem(
fileTable
)
)
}
}
} else if (lineData.startsWith("@customType(") && lineData.endsWith(
")"
)
) {
//用户自动值类型提示
val customType = lineData.subSequence(
lineData.indexOf('(') + 1,
lineData.indexOf(')')
).toString()
fileDataBase!!.getValueDao()
.searchValueByKey(
prefix,
customType,
identifiersPromptNumber
)
?.forEach {
result.add(
completionItemConverter.valueTableToCompletionItem(
it
)
)
}
} else if (lineData.startsWith("@type(") && lineData.endsWith(")")) {
val type = lineData.subSequence(
lineData.indexOf('(') + 1,
lineData.indexOf(')')
).toString()
val list = if (isEnglishMode
) {
codeDataBase!!.getCodeDao().findCodeByCodeInType(
prefix,
type,
identifiersPromptNumber
)
} else {
codeDataBase!!.getCodeDao().findCodeByTranslateInType(
prefix,
type,
identifiersPromptNumber
)
}
DebugHelper.printLog(
debugKey,
"关联了值类型[" + type + "]获取[" + (list?.size ?: -1) + "]个结果",
"值类型引用"
)
if (!list.isNullOrEmpty()) {
list.forEach {
result.add(
completionItemConverter.codeInfoToCompletionItem(
it
)
)
}
}
} else if (lineData.startsWith("@section") && lineData.endsWith(
")"
)
) {
val section = lineData.subSequence(
lineData.indexOf('(') + 1,
lineData.indexOf(')')
).toString()
codeEditor!!.textAnalyzeResult.navigation.forEach {
if (section == getSectionType(it.label)) {
result.add(
completionItemConverter.navigationItemToCompletionItem(
it
)
)
}
}
} else {
//无法分析的关联项目
result.add(
CompletionItem(
lineData,
String.format(
completionItemConverter.associatedTip,
codeInfo.translate
)
)
)
}
} else {
val show = if (isEnglishMode) {
temCodeInfo.code.contains(prefix)
} else {
temCodeInfo.translate.contains(prefix)
}
DebugHelper.printLog(
debugKey,
"值类型[" + codeInfo.type + "]项目[" + lineData + "]是否包含" + prefix + "关键字[" + show + "]",
"关联提示列表分析"
)
if (show) {
result.add(
completionItemConverter.codeInfoToCompletionItem(
temCodeInfo
)
)
}
}
true
}
}
}
} else {
//如果不包含:搜索键
val navigationList = temCodeEditor.textAnalyzeResult.navigation
var section: String? = null
if (navigationList != null && navigationList.isNotEmpty()) {
for (navigation in navigationList) {
if (navigation.line > line) {
break
} else {
section = navigation.label
}
}
}
//如果不在任何节内
if (section == null) {
return@submit
}
val trueSection = getSectionType(section)
val list = if (isEnglishMode) {
codeDataBase!!.getCodeDao().findCodeByEnglishCodeKeyFromSection(
prefix,
trueSection,
identifiersPromptNumber
)
} else {
codeDataBase!!.getCodeDao()
.findCodeByKeyFromSection(prefix, trueSection, identifiersPromptNumber)
}
if (list != null && list.isNotEmpty()) {
list.forEach {
result.add(
completionItemConverter.codeInfoToCompletionItem(it)
)
}
}
}
}
}
return if (future.get() == null) {
result
} else {
ArrayList<CompletionItem>()
}
}
override fun isEnglishMode(): Boolean {
return isEnglishMode
}
override fun setEnglish(englishMode: Boolean) {
this.isEnglishMode = englishMode
completionItemConverter.setEnglish(englishMode)
}
}

View File

@ -0,0 +1,16 @@
package com.coldmint.rust.pro.edit
import com.coldmint.rust.core.dataBean.CompileConfiguration
/**
* Rust代码标记
* @property offset Int
* @property codeBlockType CodeBlockType
*/
class RustCodeToken(
var offset: Int = 0,
var codeBlockType: CompileConfiguration.CodeBlockType = CompileConfiguration.CodeBlockType.Note
) {
}

View File

@ -1,29 +1,30 @@
package com.coldmint.rust.pro.edit
import android.content.DialogInterface
import android.graphics.Color
import android.graphics.Typeface
import android.view.ViewGroup
import android.view.LayoutInflater
import com.coldmint.rust.pro.R
import android.widget.TextView
import android.graphics.drawable.Drawable
import android.text.SpannableString
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.text.style.StyleSpan
import android.view.View
import android.widget.ImageView
import com.bumptech.glide.Glide
import android.text.style.ForegroundColorSpan
import android.util.TypedValue
import androidx.core.view.isVisible
import com.coldmint.rust.pro.databinding.EditItemBinding
import com.coldmint.rust.pro.tool.GlobalMethod
import io.github.rosemoe.sora.widget.EditorCompletionAdapter
import io.github.rosemoe.sora.widget.component.EditorCompletionAdapter
import java.util.*
/**
* Rust完成适配器
* @property layoutInflater (LayoutInflater..LayoutInflater?)
* @property spannableStringBuilder SpannableStringBuilder
* @property colorSpan ForegroundColorSpan
* @property bold StyleSpan
*/
class RustCompletionAdapter : EditorCompletionAdapter() {
private val layoutInflater by lazy {
LayoutInflater.from(context)
@ -39,20 +40,20 @@ class RustCompletionAdapter : EditorCompletionAdapter() {
isCurrentCursorPosition: Boolean
): View {
val editItem = EditItemBinding.inflate(layoutInflater, parent, false)
val completionItem = getItem(position)
val completionItem = getItem(position) as RustCompletionItem
spannableStringBuilder.clear()
val label = completionItem.label
val label = completionItem.label.toString()
spannableStringBuilder.append(label)
//节补丁
if (RustAutoComplete2.keyWord.startsWith('[') && RustAutoComplete2.keyWord.length > 1) {
RustAutoComplete2.keyWord =
RustAutoComplete2.keyWord.subSequence(1, RustAutoComplete2.keyWord.length)
if (RustAutoComplete.keyWord.startsWith('[') && RustAutoComplete.keyWord.length > 1) {
RustAutoComplete.keyWord =
RustAutoComplete.keyWord.subSequence(1, RustAutoComplete.keyWord.length)
.toString()
}
val start = label.lowercase(Locale.getDefault())
.indexOf(RustAutoComplete2.keyWord.lowercase(Locale.getDefault()))
.indexOf(RustAutoComplete.keyWord.lowercase(Locale.getDefault()))
if (start > -1) {
val end = start + RustAutoComplete2.keyWord.length
val end = start + RustAutoComplete.keyWord.length
spannableStringBuilder.setSpan(
colorSpan,
start,
@ -63,8 +64,8 @@ class RustCompletionAdapter : EditorCompletionAdapter() {
}
editItem.titleView.text = spannableStringBuilder
editItem.contentView.text = completionItem.desc
if (completionItem.extrasData != null && completionItem.extrasData.containsKey("sub")) {
editItem.subTitleView.text = completionItem.extrasData.getString("sub")
if (completionItem.subtitle != null) {
editItem.subTitleView.text = completionItem.subtitle
} else {
editItem.subTitleView.isVisible = false
}

View File

@ -0,0 +1,54 @@
package com.coldmint.rust.pro.edit
import android.graphics.drawable.Drawable
import io.github.rosemoe.sora.lang.completion.CompletionItem
import io.github.rosemoe.sora.text.Content
import io.github.rosemoe.sora.widget.CodeEditor
/**
* Rust完成器对象
* @property label String
* @constructor
*/
class RustCompletionItem(var title: String) : CompletionItem(title) {
init {
label = title
}
constructor(title: String, commit: String, subtitle: String) : this(commit) {
this.title = title
this.label = commit
this.subtitle = subtitle
}
constructor(title: String, subtitle: String, icon: Drawable?) : this(title) {
this.title = title
this.label = title
this.subtitle = subtitle
}
constructor(title: String, commit: String, sub: String, icon: Drawable?) : this(commit) {
this.title = title
this.label = commit
this.subtitle = sub
this.icon = icon
}
var cursorOffset: Int = 0
var subtitle: String? = null
/**
* 执行完成
* @param p0 CodeEditor
* @param p1 Content
* @param p2 Int
* @param p3 Int
*/
override fun performCompletion(p0: CodeEditor?, p1: Content?, p2: Int, p3: Int) {
}
}

View File

@ -0,0 +1,27 @@
package com.coldmint.rust.pro.edit
import io.github.rosemoe.sora.lang.format.Formatter
import io.github.rosemoe.sora.text.Content
import io.github.rosemoe.sora.text.TextRange
class RustFormatter : Formatter {
override fun format(p0: Content, p1: TextRange) {
}
override fun formatRegion(p0: Content, p1: TextRange, p2: TextRange) {
}
override fun setReceiver(p0: Formatter.FormatResultReceiver?) {
}
override fun isRunning(): Boolean {
return false
}
override fun destroy() {
}
}

View File

@ -0,0 +1,133 @@
package com.coldmint.rust.pro.edit
import com.coldmint.rust.core.dataBean.CompileConfiguration
import io.github.rosemoe.sora.lang.analysis.AsyncIncrementalAnalyzeManager
import io.github.rosemoe.sora.lang.analysis.IncrementalAnalyzeManager
import io.github.rosemoe.sora.lang.styling.CodeBlock
import io.github.rosemoe.sora.lang.styling.Span
import io.github.rosemoe.sora.lang.styling.TextStyle
import io.github.rosemoe.sora.text.Content
import io.github.rosemoe.sora.widget.schemes.EditorColorScheme
/**
* Rust增量分析器
*/
class RustIncrementalAnalyzeManager :
AsyncIncrementalAnalyzeManager<Int, RustCodeToken>() {
override fun getInitialState(): Int {
//获取初始状态
return 0
}
override fun stateEquals(state: Int?, another: Int?): Boolean {
return true
}
override fun tokenizeLine(
line: CharSequence?,
state: Int?,
lineIndex: Int
): IncrementalAnalyzeManager.LineTokenizeResult<Int, RustCodeToken> {
if (line.isNullOrBlank()) {
return IncrementalAnalyzeManager.LineTokenizeResult(0, null)
}
val tokens = ArrayList<RustCodeToken>()
if (line.startsWith("#")) {
//是注释
tokens.add(RustCodeToken())
return IncrementalAnalyzeManager.LineTokenizeResult(0, tokens)
}
val index = line.lastIndexOf(':')
if (index > 0) {
//是代码
tokens.add(RustCodeToken(0, CompileConfiguration.CodeBlockType.Key))
tokens.add(RustCodeToken(index, CompileConfiguration.CodeBlockType.Symbol))
tokens.add(RustCodeToken(index + 1, CompileConfiguration.CodeBlockType.Value))
return IncrementalAnalyzeManager.LineTokenizeResult(0, tokens)
}
if (line.startsWith('[') && line.endsWith(']')) {
//是节
tokens.add(RustCodeToken(0, CompileConfiguration.CodeBlockType.Section))
return IncrementalAnalyzeManager.LineTokenizeResult(0, tokens)
}
tokens.add(RustCodeToken())
return IncrementalAnalyzeManager.LineTokenizeResult(0, tokens)
}
override fun generateSpansForLine(tokens: IncrementalAnalyzeManager.LineTokenizeResult<Int, RustCodeToken>?): MutableList<Span> {
val spans = ArrayList<Span>()
val tokenList = tokens?.tokens
if (tokenList == null || tokenList.isEmpty()) {
spans.add(
Span.obtain(
0,
TextStyle.makeStyle(EditorColorScheme.COMMENT)
)
)
return spans
}
tokenList.forEach {
when (it.codeBlockType) {
CompileConfiguration.CodeBlockType.Section -> {
spans.add(
Span.obtain(
it.offset,
TextStyle.makeStyle(
EditorColorScheme.FUNCTION_NAME,
0,
true,
false,
false
)
)
)
}
CompileConfiguration.CodeBlockType.Value -> {
spans.add(
Span.obtain(
it.offset,
TextStyle.makeStyle(EditorColorScheme.COMMENT)
)
)
}
CompileConfiguration.CodeBlockType.Symbol -> {
spans.add(
Span.obtain(
it.offset,
TextStyle.makeStyle(EditorColorScheme.COMMENT)
)
)
}
CompileConfiguration.CodeBlockType.Key -> {
spans.add(
Span.obtain(
it.offset,
TextStyle.makeStyle(EditorColorScheme.KEYWORD)
)
)
}
else -> {
spans.add(
Span.obtain(
it.offset,
TextStyle.makeStyle(EditorColorScheme.COMMENT)
)
)
}
}
}
return spans
}
override fun computeBlocks(
text: Content?,
delegate: CodeBlockAnalyzeDelegate?
): MutableList<CodeBlock> {
return ArrayList<CodeBlock>()
}
}

View File

@ -2,29 +2,42 @@ package com.coldmint.rust.pro.edit
import android.content.Context
import android.util.Log
import com.coldmint.rust.core.CodeCompiler2
import com.coldmint.rust.core.dataBean.dataset.CodeDataBean
import android.os.Bundle
import com.coldmint.rust.core.database.code.CodeDataBase
import com.coldmint.rust.core.database.file.FileDataBase
import com.coldmint.rust.core.interfaces.EnglishMode
import io.github.rosemoe.sora.data.CompletionItem
import io.github.rosemoe.sora.interfaces.AutoCompleteProvider
import io.github.rosemoe.sora.interfaces.CodeAnalyzer
import io.github.rosemoe.sora.interfaces.EditorLanguage
import io.github.rosemoe.sora.interfaces.NewlineHandler
import com.coldmint.rust.core.tool.DebugHelper
import io.github.rosemoe.sora.lang.Language
import io.github.rosemoe.sora.lang.analysis.AnalyzeManager
import io.github.rosemoe.sora.lang.completion.CompletionPublisher
import io.github.rosemoe.sora.lang.completion.IdentifierAutoComplete
import io.github.rosemoe.sora.lang.format.Formatter
import io.github.rosemoe.sora.lang.smartEnter.NewlineHandleResult
import io.github.rosemoe.sora.lang.smartEnter.NewlineHandler
import io.github.rosemoe.sora.text.CharPosition
import io.github.rosemoe.sora.text.Content
import io.github.rosemoe.sora.text.ContentReference
import io.github.rosemoe.sora.text.TextRange
import io.github.rosemoe.sora.widget.CodeEditor
import io.github.rosemoe.sora.widget.SymbolPairMatch
class RustLanguage(
private val context: Context,
) : EditorLanguage, EnglishMode {
) : Language, EnglishMode {
private val mRustAnalyzer: RustAnalyzer by lazy {
RustAnalyzer()
}
private val autoComplete: RustAutoComplete2 = RustAutoComplete2(context)
private val autoComplete by lazy {
RustAutoComplete(context)
}
// private val autoComplete: RustAutoComplete = RustAutoComplete(context)
private var isEnglishMode = false
private val rustAnalyzeManager by lazy {
RustIncrementalAnalyzeManager()
}
/**
* 设置代码数据库
@ -32,7 +45,7 @@ class RustLanguage(
*/
fun setCodeDataBase(codeDataBase: CodeDataBase) {
mRustAnalyzer.setCodeDataBase(codeDataBase)
autoComplete.setCodeDataBase(codeDataBase)
// autoComplete.setCodeDataBase(codeDataBase)
}
/**
@ -40,61 +53,83 @@ class RustLanguage(
* @param codeEditor
*/
fun setCodeEditor(codeEditor: CodeEditor?) {
autoComplete.setCodeEditor(codeEditor)
// autoComplete.setCodeEditor(codeEditor)
}
fun setFileDataBase(fileDataBase: FileDataBase) {
autoComplete.setFileDataBase(fileDataBase)
// autoComplete.setFileDataBase(fileDataBase)
}
//语法分析器
override fun getAnalyzer(): CodeAnalyzer {
return mRustAnalyzer
}
// override fun getAnalyzer(): CodeAnalyzer {
// return mRustAnalyzer
// }
//自动完成器
override fun getAutoCompleteProvider(): RustAutoComplete2 {
return autoComplete
}
// override fun getAutoCompleteProvider(): RustAutoComplete {
// return autoComplete
// }
/**
* 是否为自动完成字符
*
* @param ch 字符
* @return 逻辑值
*/
override fun isAutoCompleteChar(ch: Char): Boolean {
return when (ch) {
':', '.', '_', ' ', ',' -> false
else -> true
}
// /**
// * 是否为自动完成字符
// *
// * @param ch 字符
// * @return 逻辑值
// */
// override fun isAutoCompleteChar(ch: Char): Boolean {
// return when (ch) {
// ':', '.', '_', ' ', ',' -> false
// else -> true
// }
// }
override fun getAnalyzeManager(): AnalyzeManager {
return rustAnalyzeManager
}
//获取分割进度
override fun getIndentAdvance(content: String): Int {
override fun getInterruptionLevel(): Int {
return Language.INTERRUPTION_LEVEL_STRONG
}
override fun requireAutoComplete(
p0: ContentReference,
p1: CharPosition,
p2: CompletionPublisher,
p3: Bundle
) {
val line = p0.getLine(p1.getLine())
p2.addItem(RustCompletionItem("121221"))
p2.updateList()
// autoComplete.requireAutoComplete(line,p2,p1.getLine(),p1.getColumn())
}
override fun getIndentAdvance(p0: ContentReference, p1: Int, p2: Int): Int {
return 0
}
//用标签
override fun useTab(): Boolean {
return false
return true
}
//格式化
override fun format(text: CharSequence): CharSequence {
return CodeCompiler2.format(text.toString())
override fun getFormatter(): Formatter {
return RustFormatter()
}
//符号配对之间的匹配
override fun getSymbolPairs(): SymbolPairMatch? {
override fun getSymbolPairs(): SymbolPairMatch {
return SymbolPairMatch()
}
override fun getNewlineHandlers(): Array<NewlineHandler>? {
//行处理程序,按下回车时
return null
}
//获取新线的处理程序
override fun getNewlineHandlers(): Array<NewlineHandler> {
return arrayOf()
override fun destroy() {
}
override fun isEnglishMode(): Boolean {
@ -103,7 +138,7 @@ class RustLanguage(
override fun setEnglish(englishMode: Boolean) {
mRustAnalyzer.setEnglish(englishMode)
autoComplete.setEnglish(englishMode)
// autoComplete.setEnglish(englishMode)
isEnglishMode = englishMode
}

View File

@ -1,19 +1,25 @@
package com.coldmint.rust.pro.fragments
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.os.Environment
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.view.LayoutInflater
import android.widget.AdapterView
import android.widget.ExpandableListView
import android.widget.TextView
import android.widget.Toast
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.lifecycle.MutableLiveData
import com.coldmint.dialog.CoreDialog
import com.coldmint.rust.core.LocalTemplatePackage
import com.coldmint.rust.core.dataBean.template.LocalTemplateFile
import com.coldmint.rust.core.dataBean.template.Template
import com.coldmint.rust.core.dataBean.template.TemplatePackage
import com.coldmint.rust.core.tool.FileOperator
import com.coldmint.rust.pro.FileManagerActivity
import com.coldmint.rust.pro.R
@ -35,8 +41,10 @@ class InstalledTemplateFragment : BaseFragment<FragmentInstalledTemplateBinding>
InstalledTemplateViewModel()
}
private lateinit var startTemplateParserActivity: ActivityResultLauncher<Intent>
var mTemplateAdapter: TemplateAdapter? = null
private lateinit var mTemplateAdapter: TemplateAdapter
/**
@ -69,19 +77,32 @@ class InstalledTemplateFragment : BaseFragment<FragmentInstalledTemplateBinding>
//这里做关于父项的相关操作......
val numView = view.findViewById<TextView>(R.id.template_num)
val templateClass =
mTemplateAdapter!!.getGroup(groupPosition) as LocalTemplatePackage
mTemplateAdapter.getGroup(groupPosition) as TemplatePackage
CoreDialog(requireContext()).setTitle(R.string.template_info)
.setMessage(
templateClass.getInfo()?.description
?: requireContext().getString(R.string.describe)
).setCancelable(false).setPositiveButton(R.string.delete_title) {
templateClass.getDescription()
).setCancelable(false).setPositiveButton(
if (templateClass.isLocal()) {
R.string.delete_title
} else {
R.string.de_subscription
}
) {
numView.setText(R.string.del_moding)
val handler = Handler(Looper.getMainLooper())
val scope = CoroutineScope(Job())
scope.launch {
FileOperator.delete_files(templateClass.directest)
handler.post {
templateClass.delete(
AppSettings.getValue(
AppSettings.Setting.Token,
""
)
) {
if (it) {
viewModel.loadTemplate(requireContext())
} else {
Toast.makeText(
requireContext(),
R.string.delete_error,
Toast.LENGTH_SHORT
).show()
}
}
}.setNegativeButton(R.string.dialog_cancel) {
@ -92,11 +113,25 @@ class InstalledTemplateFragment : BaseFragment<FragmentInstalledTemplateBinding>
}
true
}
viewBinding.swipeRefreshLayout.setOnRefreshListener {
viewModel.loadTemplate(requireContext())
viewBinding.swipeRefreshLayout.isRefreshing = false
}
}
override fun whenViewCreated(inflater: LayoutInflater, savedInstanceState: Bundle?) {
initAction()
startTemplateParserActivity =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
if (it.resultCode == Activity.RESULT_OK) {
Log.d("启动模板解析器", "收到成功回调,关闭界面。")
requireActivity().finish()
} else {
Log.w("启动模板解析器", "未收到有效回调。")
}
}
viewModel.createPathLiveData.observe(this) {
var relativePath = FileOperator.getRelativePath(
it,
@ -112,16 +147,24 @@ class InstalledTemplateFragment : BaseFragment<FragmentInstalledTemplateBinding>
(requireContext().getText(R.string.unit_path) as String),
relativePath
)
mTemplateAdapter?.setCreatePath(it)
if (this::mTemplateAdapter.isInitialized) {
mTemplateAdapter.setCreatePath(it)
Log.d("创建目录观察者", "模板适配器设置目录为${it}")
} else {
Log.e("创建目录观察者", "模板适配器没有设置目录。")
}
}
viewModel.setLoadCallBack {
mTemplateAdapter = TemplateAdapter(
requireContext(),
viewModel.getGroupData(),
viewModel.getItemData(),
viewModel.environmentLanguage
viewModel.environmentLanguage, startTemplateParserActivity
)
viewBinding.expandableList.setAdapter(mTemplateAdapter!!)
viewBinding.expandableList.setAdapter(mTemplateAdapter)
val path = viewModel.createPathLiveData.value.toString()
mTemplateAdapter.setCreatePath(path)
Log.d("创建目录观察者", "模板适配器设置目录为${path}")
}
viewModel.loadTemplate(requireContext())
}

View File

@ -27,17 +27,25 @@ import com.coldmint.rust.pro.databinding.ModFragmentBinding
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.viewmodel.ModViewModel
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.color.MaterialColors
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.dialog.MaterialDialogs
import com.google.android.material.shape.MaterialShapeDrawable
import com.google.android.material.snackbar.Snackbar
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import me.zhanghai.android.fastscroll.FastScrollScrollView
import me.zhanghai.android.fastscroll.FastScrollerBuilder
import java.io.File
import java.util.concurrent.Executors
import kotlin.concurrent.thread
class ModFragment : BaseFragment<ModFragmentBinding>() {
val viewModel: ModViewModel by lazy {
ModViewModel()
}
lateinit var modAdapter: ModAdapter
val needRecycling by lazy {
if (GlobalMethod.isActive) {
@ -49,88 +57,6 @@ class ModFragment : BaseFragment<ModFragmentBinding>() {
false
}
}
val executorService = Executors.newSingleThreadExecutor()
//初始化视图
fun loadMods() {
val useProgressBar = !this::modAdapter.isInitialized || modAdapter.itemCount == 0
val handler = Handler(Looper.getMainLooper())
thread {
if (useProgressBar) {
handler.post {
viewBinding.progressBar.isVisible = true
viewBinding.modError.isVisible = false
viewBinding.modErrorIcon.isVisible = false
viewBinding.modList.isVisible = false
}
}
val mod_directory = File(AppSettings.getValue(AppSettings.Setting.ModFolder, ""))
if (!mod_directory.exists()) {
mod_directory.mkdirs()
}
val files = mod_directory.listFiles()
val thisContent = requireContext()
if (files != null && files.isNotEmpty()) {
val data = ArrayList<ModClass>()
for (t in files) {
if (ModClass.isMod(t)) {
data.add(ModClass(t))
}
}
if (data.isEmpty()) {
handler.post {
showNotFindMod()
}
return@thread
}
if (useProgressBar) {
modAdapter = ModAdapter(thisContent, data)
} else {
modAdapter.setNewDataList(data)
}
modAdapter.setItemChangeEvent { changeType, i, modClass, i2 ->
if (i2 == 0) {
handler.post { loadMods() }
}
}
// modAdapter.
modAdapter.setItemEvent { i, modListItemBinding, viewHolder, modClass ->
modListItemBinding.root.setOnClickListener {
onClickItemWork(modListItemBinding, modClass)
}
modListItemBinding.root.setOnLongClickListener {
modAdapter.showDeleteItemDialog(
modClass.modName,
viewHolder.adapterPosition,
onClickPositiveButton = { d, b ->
delFile(handler, modClass, viewHolder.adapterPosition)
false
})
false
}
}
if (useProgressBar) {
handler.postDelayed({
viewBinding.modList.isVisible = true
viewBinding.modError.isVisible = false
viewBinding.modErrorIcon.isVisible = false
viewBinding.progressBar.isVisible = false
viewBinding.modList.adapter = modAdapter
}, MainActivity.hideViewDelay)
} else {
handler.post {
modAdapter.notifyDataSetChanged()
viewBinding.modList.adapter = modAdapter
}
}
} else {
handler.post {
showNotFindMod()
}
}
}
}
/**
* 删除文件
@ -142,7 +68,8 @@ class ModFragment : BaseFragment<ModFragmentBinding>() {
modClass: ModClass,
index: Int? = null
) {
executorService.submit {
val scope = CoroutineScope(Job())
scope.run {
val targetFile = modClass.modFile
val errorFolder =
File(AppSettings.dataRootDirectory + "/modErrorReport/" + modClass.modName)
@ -249,9 +176,64 @@ class ModFragment : BaseFragment<ModFragmentBinding>() {
}
}
/**
* 加载模组列表
*/
fun loadModList() {
val scope = CoroutineScope(Job())
val handler = Handler(Looper.getMainLooper())
scope.run {
val dataList = viewModel.loadMod()
handler.post {
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
}
} else {
handler.post {
viewBinding.swipeRefreshLayout.isVisible = true
viewBinding.progressBar.isVisible = false
viewBinding.modErrorIcon.isVisible = false
viewBinding.modError.isVisible = false
modAdapter = ModAdapter(requireContext(), dataList)
FastScrollerBuilder(viewBinding.modList).useMd2Style()
.setPopupTextProvider(modAdapter).build()
modAdapter.setItemEvent { i, modListItemBinding, viewHolder, modClass ->
modListItemBinding.root.setOnClickListener {
onClickItemWork(modListItemBinding, modClass)
}
modListItemBinding.root.setOnLongClickListener {
modAdapter.showDeleteItemDialog(
modClass.modName,
viewHolder.adapterPosition,
onClickPositiveButton = { d, b ->
delFile(handler, modClass, viewHolder.adapterPosition)
false
})
false
}
}
viewBinding.modList.adapter = modAdapter
}
}
}
}
override fun onResume() {
super.onResume()
loadMods()
loadModList()
}
@SuppressLint("RestrictedApi")
@ -346,16 +328,16 @@ class ModFragment : BaseFragment<ModFragmentBinding>() {
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
}
// /**
// * 显示没有找到模组
// */
// 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
// }
override fun getViewBindingObject(layoutInflater: LayoutInflater): ModFragmentBinding {
return ModFragmentBinding.inflate(layoutInflater)
@ -369,5 +351,10 @@ class ModFragment : BaseFragment<ModFragmentBinding>() {
DividerItemDecoration.VERTICAL
)
)
viewBinding.swipeRefreshLayout.setOnRefreshListener {
loadModList()
viewBinding.swipeRefreshLayout.isRefreshing = false
}
viewModel.loadMod()
}
}

View File

@ -2,12 +2,17 @@ package com.coldmint.rust.pro.fragments
import android.os.Bundle
import android.view.LayoutInflater
import android.widget.Toast
import androidx.core.view.isVisible
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import com.coldmint.rust.core.dataBean.webTemplate.WebTemplatePackageListData
import com.coldmint.dialog.CoreDialog
import com.coldmint.rust.core.dataBean.ApiResponse
import com.coldmint.rust.core.dataBean.WebTemplatePackageListData
import com.coldmint.rust.core.interfaces.ApiCallBack
import com.coldmint.rust.core.web.ServerConfiguration
import com.coldmint.rust.core.web.TemplatePhp
import com.coldmint.rust.pro.R
import com.coldmint.rust.pro.adapters.WebTemplateAdapter
import com.coldmint.rust.pro.base.BaseFragment
import com.coldmint.rust.pro.databinding.FragmentTemplateCommunityBinding
@ -45,6 +50,75 @@ class TemplateCommunityFragment : BaseFragment<FragmentTemplateCommunityBinding>
viewBinding.loadView.isVisible = false
viewBinding.errorLayout.isVisible = false
val adapter = WebTemplateAdapter(requireContext(), t.data)
adapter.setItemEvent { i, itemWebTemplateBinding, viewHolder, data ->
itemWebTemplateBinding.button.setOnClickListener {
var subscribe = data.subscribe
if (subscribe) {
CoreDialog(requireContext()).setTitle(R.string.de_subscription)
.setMessage(
String.format(
getString(R.string.de_subscription_msg),
data.name
)
).setPositiveButton(R.string.dialog_ok) {
//退订
TemplatePhp.instance.deleteSubscription(token, data.id,
object : ApiCallBack<ApiResponse> {
override fun onResponse(t: ApiResponse) {
if (t.code == ServerConfiguration.Success_Code) {
itemWebTemplateBinding.button.setText(R.string.subscription)
data.subscribe = false
} else {
Toast.makeText(
requireContext(),
t.message,
Toast.LENGTH_SHORT
).show()
}
}
override fun onFailure(e: Exception) {
e.printStackTrace()
Toast.makeText(
requireContext(),
R.string.network_error,
Toast.LENGTH_SHORT
).show()
}
})
}.setNegativeButton(R.string.dialog_cancel) {
}.setCancelable(false).show()
} else {
TemplatePhp.instance.subscription(token, data.id,
object : ApiCallBack<ApiResponse> {
override fun onResponse(t: ApiResponse) {
if (t.code == ServerConfiguration.Success_Code) {
itemWebTemplateBinding.button.setText(R.string.de_subscription)
data.subscribe = true
} else {
Toast.makeText(
requireContext(),
t.message,
Toast.LENGTH_SHORT
).show()
}
}
override fun onFailure(e: Exception) {
e.printStackTrace()
Toast.makeText(
requireContext(),
R.string.network_error,
Toast.LENGTH_SHORT
).show()
}
})
}
}
}
viewBinding.recyclerView.adapter = adapter
FastScrollerBuilder(viewBinding.recyclerView).useMd2Style()
.setPopupTextProvider(adapter).build()

View File

@ -14,8 +14,7 @@ import com.coldmint.rust.core.tool.FileOperator
import com.coldmint.rust.core.tool.LocalVariableName
import com.coldmint.rust.core.web.Dynamic
import com.coldmint.rust.pro.R
import io.github.rosemoe.sora.data.CompletionItem
import io.github.rosemoe.sora.data.NavigationItem
import com.coldmint.rust.pro.edit.RustCompletionItem
import java.io.File
import java.lang.StringBuilder
@ -129,9 +128,9 @@ class CompletionItemConverter private constructor() : EnglishMode {
/**
* 节信息转换为自动完成对象
* @param sectionInfo SectionInfo
* @return CompletionItem
* @return RustCompletionItem
*/
fun sectionInfoToCompletionItem(sectionInfo: SectionInfo): CompletionItem {
fun sectionInfoToCompletionItem(sectionInfo: SectionInfo): RustCompletionItem {
if (!isInitComplete) {
NullPointerException("没有初始化。")
}
@ -147,14 +146,14 @@ class CompletionItemConverter private constructor() : EnglishMode {
"[" + sectionInfo.translate + end
}
val completionItem = if (isEnglishMode) {
CompletionItem(
RustCompletionItem(
sectionInfo.code,
commit,
section,
boxDrawable
)
} else {
CompletionItem(
RustCompletionItem(
sectionInfo.translate,
commit,
section,
@ -173,18 +172,18 @@ class CompletionItemConverter private constructor() : EnglishMode {
* 本地变量转自动完成对象
* @param localVariableName LocalVariableName
* @param previousText String? 之前的内容(冒号后面的值)
* @return CompletionItem
* @return RustCompletionItem
*/
fun localVariableNameToCompletionItem(
localVariableName: LocalVariableName,
previousText: String? = null
): CompletionItem {
): RustCompletionItem {
val commit = if (previousText == null) {
"\${" + localVariableName.name + "}"
} else {
previousText + "\${" + localVariableName.name + "}"
}
return CompletionItem(
return RustCompletionItem(
localVariableName.name,
commit,
variableName, boxDrawable
@ -194,21 +193,21 @@ class CompletionItemConverter private constructor() : EnglishMode {
/**
* 转换代码信息到自动完成对象
* @param codeInfo CodeInfo
* @return CompletionItem
* @return RustCompletionItem
*/
fun codeInfoToCompletionItem(codeInfo: CodeInfo): CompletionItem {
fun codeInfoToCompletionItem(codeInfo: CodeInfo): RustCompletionItem {
if (!isInitComplete) {
NullPointerException("没有初始化。")
}
val typeInfo = getValueType(codeInfo.type)
val completionItem = if (isEnglishMode) {
CompletionItem(
RustCompletionItem(
codeInfo.code,
codeInfo.code + typeInfo?.external,
codeInfo.description, boxDrawable
)
} else {
CompletionItem(
RustCompletionItem(
codeInfo.translate,
codeInfo.translate + typeInfo?.external,
codeInfo.description, boxDrawable
@ -218,7 +217,7 @@ class CompletionItemConverter private constructor() : EnglishMode {
if (typeList != null && typeList.isNotBlank()) {
val bundle = Bundle()
bundle.putString("list", typeList)
completionItem.extrasData = bundle
// completionItem.extrasData = bundle
}
val offset = typeInfo?.offset
if (offset != null && offset.isNotBlank()) {
@ -260,7 +259,7 @@ class CompletionItemConverter private constructor() : EnglishMode {
* @param valueTable ValueTable
* @return CompletionItem
*/
fun valueTableToCompletionItem(valueTable: ValueTable): CompletionItem {
fun valueTableToCompletionItem(valueTable: ValueTable): RustCompletionItem {
if (isInitComplete) {
NullPointerException("没有初始化。")
}
@ -278,7 +277,7 @@ class CompletionItemConverter private constructor() : EnglishMode {
}
}
}
return CompletionItem(valueTable.keyWord, desc, boxDrawable)
return RustCompletionItem(valueTable.keyWord, desc, boxDrawable)
}
/**
@ -286,23 +285,23 @@ class CompletionItemConverter private constructor() : EnglishMode {
* @param navigationItem NavigationItem
* @return CompletionItem
*/
fun navigationItemToCompletionItem(navigationItem: NavigationItem): CompletionItem {
val name = SourceFile.getAbsoluteSectionName(navigationItem.label)
val type = SourceFile.getSectionType(navigationItem.label)
return CompletionItem(
name,
name,
type,
boxDrawable
)
}
// fun navigationItemToCompletionItem(navigationItem: NavigationItem): RustCompletionItem {
// val name = SourceFile.getAbsoluteSectionName(navigationItem.label)
// val type = SourceFile.getSectionType(navigationItem.label)
// return RustCompletionItem(
// name,
// name,
// type,
// boxDrawable
// )
// }
/**
* 文件信息转自动完成对象
* @param fileTable FileTable
* @return CompletionItem
*/
fun fileTableToCompletionItem(fileTable: FileTable): CompletionItem {
fun fileTableToCompletionItem(fileTable: FileTable): RustCompletionItem {
if (!isInitComplete) {
NullPointerException("没有初始化。")
}
@ -335,7 +334,7 @@ class CompletionItemConverter private constructor() : EnglishMode {
}
}
val completionItem =
CompletionItem(
RustCompletionItem(
fileTable.fileName,
stringBuilder.toString(),
fileTable.type, drawable
@ -353,7 +352,7 @@ class CompletionItemConverter private constructor() : EnglishMode {
if (rootCodeName == null) {
throw NullPointerException("未设置Root名称")
}
return CompletionItem(
return RustCompletionItem(
fileTable.fileName,
fileTable.fileName,
fileTable.type, fileDrawable

View File

@ -4,12 +4,16 @@ import android.content.Context
import android.util.Log
import androidx.lifecycle.MutableLiveData
import com.coldmint.rust.core.LocalTemplatePackage
import com.coldmint.rust.core.dataBean.SubscriptionData
import com.coldmint.rust.core.dataBean.template.LocalTemplateFile
import com.coldmint.rust.core.dataBean.template.Template
import com.coldmint.rust.core.dataBean.template.TemplatePackage
import com.coldmint.rust.core.interfaces.ApiCallBack
import com.coldmint.rust.core.interfaces.FileFinderListener
import com.coldmint.rust.core.tool.FileFinder2
import com.coldmint.rust.core.tool.FileOperator
import com.coldmint.rust.core.web.ServerConfiguration
import com.coldmint.rust.core.web.TemplatePhp
import com.coldmint.rust.pro.base.BaseViewModel
import com.coldmint.rust.pro.tool.AppSettings
import org.json.JSONException
@ -80,8 +84,36 @@ class InstalledTemplateViewModel : BaseViewModel() {
fun loadTemplate(context: Context) {
groupList.clear()
itemList.clear()
val token = AppSettings.getValue(AppSettings.Setting.Token,"")
TemplatePhp.instance.getSubscriptionDataList(token,object :ApiCallBack<SubscriptionData>{
override fun onResponse(t: SubscriptionData) {
if (t.code == ServerConfiguration.Success_Code){
Log.d("加载网络订阅模板", "正在处理。")
t.data.forEach {
groupList.add(it)
val temList = ArrayList<Template>()
itemList.add(temList)
it.templateList.forEach {
temList.add(it)
}
}
loadLocalTemplate(context)
loadCallBack?.invoke()
}else{
Log.w("加载网络订阅模板", t.message)
loadLocalTemplate(context)
loadCallBack?.invoke()
}
}
override fun onFailure(e: Exception) {
e.printStackTrace()
Log.e("加载网络订阅模板", e.toString())
loadLocalTemplate(context)
loadCallBack?.invoke()
}
})
}
/**
@ -134,7 +166,7 @@ class InstalledTemplateViewModel : BaseViewModel() {
Log.d("加载本地模板", "已成功分配" + file.absolutePath)
}
} else {
Log.e("加载本地模板", "无法分配" + file.absolutePath)
Log.w("加载本地模板", "无法分配" + file.absolutePath)
}
return true
}

View File

@ -0,0 +1,58 @@
package com.coldmint.rust.pro.viewmodel
import android.os.Environment
import android.util.Log
import com.coldmint.rust.core.ModClass
import com.coldmint.rust.pro.base.BaseViewModel
import com.coldmint.rust.pro.tool.AppSettings
import java.io.File
/**
* 模组ViewModel
*/
class ModViewModel : BaseViewModel() {
/**
* 加载模组
*/
fun loadMod(): ArrayList<ModClass>? {
val key = "加载模组列表"
val modFolder = File(
AppSettings.getValue(
AppSettings.Setting.ModFolder,
Environment.getExternalStorageDirectory().absolutePath + "/rustedWarfare/units/"
)
)
if (modFolder.exists()) {
if (!modFolder.isDirectory) {
Log.e(key, "模组文件夹${modFolder},不是文件夹。")
return null
}
val fileList = modFolder.listFiles()
if (fileList.isNullOrEmpty()) {
Log.e(key, "模组文件夹${modFolder},为空。")
return null
}
val arrayList = ArrayList<ModClass>()
fileList.forEach {
val isMod = ModClass.isMod(it)
if (isMod) {
arrayList.add(ModClass(it))
Log.d(key, "已添加${it.absolutePath}")
} else {
Log.e(key, "${it.absolutePath} 不是模组。")
}
}
return if (arrayList.isEmpty()){
return null
}else{
arrayList
}
} else {
Log.e(key, "模组文件夹${modFolder}不存在。")
return null
}
}
}

View File

@ -3,6 +3,7 @@ package com.coldmint.rust.pro.viewmodel
import android.content.Context
import android.util.Log
import androidx.lifecycle.viewModelScope
import com.coldmint.rust.core.SourceFile
import com.coldmint.rust.core.dataBean.InputParserDataBean
import com.coldmint.rust.core.dataBean.IntroducingDataBean
import com.coldmint.rust.core.dataBean.ListParserDataBean
@ -11,16 +12,24 @@ import com.coldmint.rust.core.interfaces.TemplateParser
import com.coldmint.rust.core.templateParser.InputParser
import com.coldmint.rust.core.templateParser.IntroducingParser
import com.coldmint.rust.core.templateParser.ListParser
import com.coldmint.rust.core.tool.FileOperator
import com.coldmint.rust.pro.base.BaseViewModel
import com.coldmint.rust.pro.tool.AppSettings
import com.google.gson.Gson
import org.json.JSONArray
import org.json.JSONObject
import java.io.File
class TemplateParserViewModel : BaseViewModel() {
//json数据
private var jsonData: JSONObject? = null
private var template: Template? = null
private lateinit var arrayList :ArrayList<TemplateParser>
//创建目录
private var createDirectory: String? = null
/**
* 设置模板数据
@ -32,6 +41,15 @@ class TemplateParserViewModel : BaseViewModel() {
}
/**
* 设置创建目录
* @param path String
*/
fun setCreateDirectory(path: String) {
createDirectory = path
}
/**
* 获取源代码
* @return String
@ -51,14 +69,105 @@ class TemplateParserViewModel : BaseViewModel() {
}
/**
* 构建文件
* @param context Context
* @param fileName String
* @return Boolean
*/
fun buildFile(context: Context, fileName: String): Boolean {
if (createDirectory == null) {
Log.e("构建文件", "没有设置创建目录。")
return false
}
val index = fileName.lastIndexOf('.')
val independentFolder = AppSettings.getValue(AppSettings.Setting.IndependentFolder, true)
val createPath = if (independentFolder) {
val folderName =
if (index > -1) {
fileName.substring(0 until index)
} else {
fileName
}
"$createDirectory/$folderName"
} else {
createDirectory
}
Log.d("构建文件", "是否需要独立创建文件夹${independentFolder} 文件夹目录${createPath}")
val folder = File(createPath)
if (folder.exists()) {
Log.e("构建文件", "创建目录${createPath}已存在。")
return false
}
folder.mkdirs()
val path = File(
createPath + "/" + if (index > -1) {
fileName
} else {
"$fileName.ini"
}
)
if (path.exists()) {
Log.e("构建文件", "目标文件${path}已存在。")
return false
}
return FileOperator.writeFile(path, generatingCode(context))
}
/**
* 生成代码
* @return String
*/
private fun generatingCode(context: Context): String {
val staticCode = getCode()
//如果为空,那么返回空
if (staticCode.isBlank()) {
Log.e("获取模板解析器", "静态代码为空。")
return staticCode
}
val sourceFile = SourceFile(staticCode)
val parserList = getTemplateParserList(context)
if (parserList.isEmpty()) {
Log.w("生成代码", "此模板没有解析器,返回静态代码。")
return staticCode
} else {
parserList.forEach {
if (it.needParse) {
val input = it.getInput()
if (input.isBlank()) {
Log.w("生成代码", "模板${it.code}输入为空,跳过处理。")
} else {
Log.d("生成代码", "已将${it.code}的值设置为${input}")
val section = it.section
if (section == null) {
sourceFile.writeValue(it.code, input)
} else {
sourceFile.writeValueFromSection(it.code, input, section)
}
}
} else {
Log.d("生成代码", "模板${it.code}无需处理。")
}
}
return sourceFile.text
}
}
/**
* 获取模板解析器列表
* @param context Context
* @return ArrayList<TemplateParser>
*/
fun getTemplateParserList(context: Context): ArrayList<TemplateParser> {
if (this::arrayList.isInitialized)
{
Log.d("获取模板解析器","已经被调用了一次,返回成员变量")
return arrayList
}
arrayList = ArrayList()
val gson = Gson()
val arrayList = ArrayList<TemplateParser>()
val jsonArray = jsonData?.getJSONArray("action")
if (jsonArray == null) {
Log.e("获取模板解析器", "此模板没有action无法读取。")

View File

@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="200dp"
android:height="200dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:pathData="M823.3,303.6c-12.5,-12.4 -32.9,-12.4 -45.3,0L429.1,652.5 246,459.3c-12.5,-12.4 -32.9,-12.4 -45.3,0 -12.4,12.5 -12.4,32.9 0,45.3l205.8,215.8c6.2,6.2 14.4,9.3 22.6,9.3 8.2,0 16.4,-3.1 22.7,-9.3l371.5,-371.5c12.4,-12.5 12.4,-32.8 0,-45.3z"
android:fillColor="#FF000000"/>
</vector>

View File

@ -0,0 +1,6 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13c0,-3.87 -3.13,-7 -7,-7zM7,9c0,-2.76 2.24,-5 5,-5s5,2.24 5,5c0,2.88 -2.88,7.19 -5,9.88C9.92,16.21 7,11.85 7,9z"/>
<path android:fillColor="@android:color/white" android:pathData="M12,9m-2.5,0a2.5,2.5 0,1 1,5 0a2.5,2.5 0,1 1,-5 0"/>
</vector>

View File

@ -20,6 +20,7 @@
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
android:background="@android:color/transparent"
android:layout_width="match_parent"
android:layout_height="wrap_content">

View File

@ -6,51 +6,34 @@
android:layout_height="match_parent">
<RelativeLayout
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/coordinator"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true">
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:windowBackground"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="?android:attr/windowBackground"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:id="@id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:theme="?attr/actionBarStyle" />
android:layout_height="?attr/actionBarSize" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
android:id="@id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:windowBackground"
android:layout_marginBottom="8dp"
android:background="@android:color/transparent"
android:contentDescription="@string/action"
app:tabMode="scrollable"
app:tabTextAppearance="@style/TabLayoutTextStyle" />
</com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/recyclerview"
android:layout_below="@id/coordinator"
android:gravity="center"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
<ProgressBar
android:id="@+id/myProgressBar"
@ -61,12 +44,12 @@
android:id="@+id/codeEditor"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
android:layout_above="@id/recyclerview"
android:layout_below="@id/appBarLayout" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview"
android:id="@id/recyclerview"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
@ -78,5 +61,4 @@
<include layout="@layout/edit_end" />
<include layout="@layout/edit_start" />
</androidx.drawerlayout.widget.DrawerLayout>

View File

@ -7,12 +7,11 @@
android:animateLayoutChanges="true"
android:fitsSystemWindows="false">
<com.google.android.material.circularreveal.coordinatorlayout.CircularRevealCoordinatorLayout
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/rootLayout"
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"
@ -27,13 +26,21 @@
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
app:tabMode="fixed"
app:tabTextAppearance="@style/TabLayoutTextStyle">
android:background="@android:color/transparent"
android:visibility="gone">
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="已安装" />
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="模板社区" />
</com.google.android.material.tabs.TabLayout>
</com.google.android.material.appbar.AppBarLayout>
<fragment
@ -41,6 +48,8 @@
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="8dp"
app:defaultNavHost="true"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />
@ -55,16 +64,15 @@
android:text="@string/create"
app:icon="@drawable/add" />
</com.google.android.material.circularreveal.coordinatorlayout.CircularRevealCoordinatorLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<com.google.android.material.navigation.NavigationView
android:id="@+id/navaiagtion"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:elevation="2dp"
android:fitsSystemWindows="false"
app:elevation="2dp"
app:menu="@menu/menu_drawer_left" />
</androidx.drawerlayout.widget.DrawerLayout>

View File

@ -8,6 +8,7 @@
android:fitsSystemWindows="true"
tools:context=".OrderListActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -18,6 +19,16 @@
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" />
<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"
app:tabMode="scrollable">
</com.google.android.material.tabs.TabLayout>
</com.google.android.material.appbar.AppBarLayout>
@ -31,8 +42,6 @@
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
<ProgressBar
android:id="@+id/progressBar"
android:layout_width="wrap_content"
@ -47,27 +56,20 @@
android:visibility="gone" />
<LinearLayout
android:visibility="gone"
android:id="@+id/contentLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
android:orientation="vertical"
android:visibility="gone">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
app:tabMode="scrollable"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewPager2"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
android:layout_height="match_parent" />
</LinearLayout>
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -86,7 +86,7 @@
</LinearLayout>
<com.google.android.material.floatingactionbutton.FloatingActionButton
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@ -94,6 +94,7 @@
android:layout_alignParentBottom="true"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
android:src="@drawable/complete" />
app:icon="@drawable/build"
android:text="@string/build_unit"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -5,41 +5,33 @@
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:windowBackground"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:theme="?attr/actionBarStyle"
app:layout_collapseMode="pin"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
android:layout_height="?attr/actionBarSize" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
android:background="@android:color/transparent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed"
app:tabTextAppearance="@style/TabLayoutTextStyle">
android:layout_height="wrap_content">
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/all_units" />
android:text="全部" />
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/recently_opened" />
android:text="最近" />
</com.google.android.material.tabs.TabLayout>
</com.google.android.material.appbar.AppBarLayout>
@ -47,17 +39,18 @@
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="8dp"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="8dp"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
android:src="@drawable/add" />
android:text="@string/create_unit"
app:icon="@drawable/add" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_height="wrap_content"
android:background="?android:windowBackground"
android:padding="8dp">
@ -10,14 +10,13 @@
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_centerVertical="true"
android:layout_marginRight="16dp"
android:layout_marginEnd="16dp"
android:src="@drawable/image" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toRightOf="@id/iconView"
android:gravity="center_vertical"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/iconView"
android:orientation="vertical">
<TextView

View File

@ -1,5 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/swipeRefreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
@ -30,6 +35,8 @@
<ExpandableListView
android:id="@+id/expandableList"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
android:layout_height="match_parent" />
</LinearLayout>
</LinearLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

View File

@ -21,6 +21,8 @@
<TextView
android:ellipsize="end"
android:singleLine="true"
android:id="@+id/describeView"
style="@style/TextAppearance.Material3.BodyMedium"
android:layout_width="wrap_content"

View File

@ -23,21 +23,29 @@
<TextView
android:id="@+id/modError"
style="@style/TextAppearance.Material3.TitleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/not_find_mod"
style="@style/TextAppearance.Material3.TitleLarge"
android:visibility="gone" />
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipeRefreshLayout"
android:layout_width="match_parent"
android:visibility="gone"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/modList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="8dp"
android:layout_marginTop="8dp"
android:layout_marginRight="8dp"
android:visibility="gone" />
android:layout_marginRight="8dp" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</LinearLayout>

View File

@ -786,7 +786,7 @@
<string name="change_server_complete">The server has changed.</string>
<string name="order_manager">The order management</string>
<string name="log_out">logout</string>
<string name="user_info">%1$s uid:%2$s</string>
<string name="user_info">%1$s uid:%2$s location:%3$s</string>
<string name="use_coupon">Will use coupons to create orders, still continue\? (After creating the order, use the coupon)</string>
<string name="use">use</string>
<string name="account_or_email">Account/email</string>

View File

@ -785,7 +785,7 @@
<string name="change_server_complete">サーバーを変更しました。</string>
<string name="order_manager">注文管理</string>
<string name="log_out">掲載</string>
<string name="user_info">最近ログイン:%1$s uid:%2$s</string>
<string name="user_info">最近ログイン:%1$s uid:%2$s 住所:%3$s</string>
<string name="use_coupon">クーポンを使った注文を作成しますが、継続しますか\?(注文作成完了後、クーポンを消費)</string>
<string name="use">使用</string>
<string name="account_or_email">アカウント/ eメール</string>

View File

@ -785,7 +785,7 @@
<string name="change_server_complete">Сервер был изменен.</string>
<string name="order_manager">Управление заказом</string>
<string name="log_out">напечата</string>
<string name="user_info">Зарегистрировано недавно :% $uid:% $2</string>
<string name="user_info">Зарегистрировано недавно :%1$s uid:%2$s местожительство:%3$s</string>
<string name="use_coupon">Мы используем купоны, чтобы создать порядок. (после создания заказа, купоны будут расходуться)</string>
<string name="use">использова</string>
<string name="account_or_email">Номер счета/письмо</string>

View File

@ -25,6 +25,7 @@
<string name="create_unit_complete">单位创建完成</string>
<string name="create_unit_failed">单位创建失败</string>
<string name="create_uniting">正在构建单位...</string>
<string name="build_unit">构建单位</string>
<string name="dialog_ok">确定</string>
<string name="activation_app">激活铁锈助手</string>
<string name="activation_app_tip">您的激活时间已过,请激活铁锈助手。</string>
@ -98,7 +99,7 @@
<string name="enter_file_path">请输入文件路径。</string>
<string name="create_bookmark">创建书签</string>
<string name="name_error">请输入模组名称。</string>
<string name="unit_name_error">请输入单位名称。</string>
<string name="file_name_error">请输入文件名称。</string>
<string name="action_name_error">请输入活动名称。</string>
<string name="database_null">此数据集无法加载,错误原因:%1$s。</string>
<string name="describe_error">请输入描述。</string>
@ -748,6 +749,7 @@
<string name="undo">撤销</string>
<string name="redo">重做</string>
<string name="del_mod">删除</string>
<string name="delete_error">删除失败。</string>
<string name="need_save">[未保存]%1$s</string>
<string name="game_data_and_synchronization">游戏数据与同步</string>
<string name="game_data_and_synchronization_describe">管理已同步的游戏数据。</string>
@ -800,7 +802,7 @@
<string name="change_server_complete">已更改服务器。</string>
<string name="order_manager">订单管理</string>
<string name="log_out">登出</string>
<string name="user_info">最近登录:%1$s uid:%2$s</string>
<string name="user_info">最近登录:%1$s uid:%2$s ip归属地:%3$s</string>
<string name="use_coupon">将使用优惠券创建订单,仍继续嘛?(创建订单完成后,将优惠券消耗)</string>
<string name="use">使用</string>
<string name="account_or_email">账号/电子邮件</string>
@ -873,6 +875,7 @@
<string name="template_id">模板id</string>
<string name="subscription">订阅</string>
<string name="de_subscription">退订</string>
<string name="de_subscription_msg">要退订%1$s嘛?</string>
<!-- <string name="search_suggestions_null">无搜索建议。</string>-->
<!-- <string name="search_suggestions_number">共%1$d个搜索建议。</string>-->

View File

@ -1,5 +1,7 @@
package com.coldmint.rust.core
import android.os.Handler
import android.os.Looper
import com.coldmint.rust.core.dataBean.TemplateDataBean
import com.coldmint.rust.core.dataBean.template.TemplateInfo
import com.coldmint.rust.core.dataBean.template.TemplatePackage
@ -64,6 +66,18 @@ class LocalTemplatePackage(val directest: File) : TemplatePackage {
return info?.name ?: directest.name
}
override fun getDescription(): String {
val info = getInfo()
return info?.description ?: ""
}
override fun delete(token: String, func: (Boolean) -> Unit) {
func.invoke(FileOperator.delete_files(directest))
}
override fun isLocal(): Boolean {
return true
}
/**

View File

@ -497,10 +497,10 @@ class SourceFile(text: String) {
stringBuilder.append(value)
stringBuilder.append(sinfo.substring(endnum, sinfo.length - 1))
stringBuilder.append(info.substring(sectionendnum, info.length - 2))
if (hasSymbol) {
text = stringBuilder.toString()
text = if (hasSymbol) {
stringBuilder.toString()
} else {
text = stringBuilder.substring(1)
stringBuilder.substring(1)
}
return true
}

View File

@ -155,7 +155,7 @@ data class CompileConfiguration(
* Reference 引用是一种特殊的数据类型编译器会尝试编译此值若无法编译则使用原始值
*/
enum class CodeBlockType {
Key, Value, Section, Note, VariableName, Reference
Key, Value, Section, Note, VariableName, Reference, Symbol
}
/**

View File

@ -0,0 +1,136 @@
package com.coldmint.rust.core.dataBean
import android.util.Log
import com.coldmint.rust.core.dataBean.template.Template
import com.coldmint.rust.core.dataBean.template.TemplatePackage
import com.coldmint.rust.core.interfaces.ApiCallBack
import com.coldmint.rust.core.web.ServerConfiguration
import com.coldmint.rust.core.web.TemplatePhp
import com.google.gson.annotations.SerializedName
import org.json.JSONObject
/**
* 订阅信息
* @property code Int
* @property `data` List<Data>
* @property message String
* @constructor
*/
data class SubscriptionData(
@SerializedName("code")
val code: Int,
@SerializedName("data")
val `data`: List<Data>,
@SerializedName("message")
val message: String
) {
data class Data(
@SerializedName("appVersionName")
val appVersionName: String,
@SerializedName("appVersionNumber")
val appVersionNumber: String,
@SerializedName("createTime")
val createTime: String,
@SerializedName("describe")
val describe: String,
@SerializedName("developer")
val developer: String,
@SerializedName("id")
val id: String,
@SerializedName("modificationTime")
val modificationTime: String,
@SerializedName("name")
val name1: String,
@SerializedName("public")
val `public`: String,
@SerializedName("subscriptionNumber")
val subscriptionNumber: String,
@SerializedName("templateList")
val templateList: List<Template>,
@SerializedName("templateNumber")
val templateNumber: String,
@SerializedName("versionName")
val versionName: String,
@SerializedName("versionNumber")
val versionNumber: String
) : TemplatePackage {
data class Template(
@SerializedName("content")
val content: String,
@SerializedName("createTime")
val createTime: String,
@SerializedName("deleted")
val deleted: String,
@SerializedName("developer")
val developer: String,
@SerializedName("id")
val id: String,
@SerializedName("modificationTime")
val modificationTime: String,
@SerializedName("packageId")
val packageId: String,
@SerializedName("title")
val title: String
) : com.coldmint.rust.core.dataBean.template.Template {
private val jsonObject: JSONObject by lazy {
JSONObject(content)
}
override fun getJson(): JSONObject {
return jsonObject
}
override fun getName(language: String): String {
return title
}
override fun getIcon(): Any? {
return null
}
override fun isLocal(): Boolean {
return false
}
override fun getLink(): String {
return id
}
}
override fun getName(): String {
return name1
}
override fun getDescription(): String {
return describe
}
override fun delete(token: String, func: (Boolean) -> Unit) {
TemplatePhp.instance.deleteSubscription(token, id, object : ApiCallBack<ApiResponse> {
override fun onResponse(t: ApiResponse) {
if (t.code == ServerConfiguration.Success_Code) {
Log.d("取消订阅", "成功。")
func.invoke(true)
} else {
Log.e("取消订阅", t.message)
func.invoke(false)
}
}
override fun onFailure(e: Exception) {
e.printStackTrace()
Log.e("取消订阅", e.toString())
func.invoke(false)
}
})
}
override fun isLocal(): Boolean {
return false
}
}
}

View File

@ -1,4 +1,4 @@
package com.coldmint.rust.core.dataBean.webTemplate
package com.coldmint.rust.core.dataBean
import com.google.gson.annotations.SerializedName
@ -22,10 +22,6 @@ data class WebTemplatePackageListData(
val describe: String,
@SerializedName("developer")
val developer: String,
@SerializedName("downloadNumber")
val downloadNumber: Int,
@SerializedName("templateNumber")
val templateNumber: Int,
@SerializedName("id")
val id: String,
@SerializedName("modificationTime")
@ -33,12 +29,16 @@ data class WebTemplatePackageListData(
@SerializedName("name")
val name: String,
@SerializedName("public")
val `public`: Boolean,
val `public`: String,
@SerializedName("subscribe")
var subscribe: Boolean,
@SerializedName("subscriptionNumber")
val subscriptionNumber: String,
@SerializedName("templateNumber")
val templateNumber: String,
@SerializedName("versionName")
val versionName: String,
@SerializedName("versionNumber")
val versionNumber: String,
@SerializedName("subscribe")
val subscribe: Boolean
val versionNumber: String
)
}

View File

@ -9,8 +9,27 @@ interface TemplatePackage {
* 实现获取名称方法
* @return String
*/
fun getName():String
fun getName(): String
/**
* 获取描述
* @return String
*/
fun getDescription(): String
/**
* 实现删除方法本地模板删除远程模板退订
* @return Boolean
*/
fun delete(token: String, func: (Boolean) -> Unit)
/**
* 是否为本地模板包
* @return Boolean
*/
fun isLocal():Boolean
}

View File

@ -0,0 +1,70 @@
package com.coldmint.rust.core.dataBean.template
import com.google.gson.annotations.SerializedName
import org.json.JSONObject
/**
* 网络模板详情
* @property code Int
* @property `data` Data
* @property message String
* @constructor
*/
data class WebTemplateData(
@SerializedName("code")
val code: Int,
@SerializedName("data")
val `data`: Data,
@SerializedName("message")
val message: String
) {
data class Data(
@SerializedName("content")
val content: String,
@SerializedName("createTime")
val createTime: String,
@SerializedName("deleted")
val deleted: String,
@SerializedName("developer")
val developer: String,
@SerializedName("id")
val id: String,
@SerializedName("modificationTime")
val modificationTime: String,
@SerializedName("packageId")
val packageId: String,
@SerializedName("title")
val title: String,
) : Template {
private lateinit var jsonObject: JSONObject
override fun getJson(): JSONObject {
if (!this::jsonObject.isInitialized) {
jsonObject = JSONObject(content)
}
return jsonObject
}
override fun getName(language: String): String {
return if (getJson().has("name_$language")) {
return getJson().getString("name_$language")
} else {
return getJson().getString("name")
}
}
override fun getIcon(): Any? {
return null
}
override fun isLocal(): Boolean {
return false
}
override fun getLink(): String {
return id
}
}
}

View File

@ -19,6 +19,7 @@ data class SpaceInfoData(
val praise: Int,
val expirationTime: String,
val userName: String,
val gender: Int
val gender: Int,
val location: String
)
}

View File

@ -10,7 +10,7 @@ interface TemplateParser {
/**
* 实现获取用户输入
*/
val input: String
fun getInput(): String
/**
* 实现实例化视图

View File

@ -18,8 +18,10 @@ class InputParser(val context: Context, val data: InputParserDataBean) : Templat
private val parserInputBinding: ParserInputBinding =
ParserInputBinding.inflate(LayoutInflater.from(context))
override val input: String
get() = parserInputBinding.inputView.text.toString()
override fun getInput(): String {
return parserInputBinding.inputView.text.toString()
}
override val contextView: View
get() {

View File

@ -12,6 +12,7 @@ import com.coldmint.rust.core.databinding.ParserIntroduceBinding
import com.coldmint.rust.core.interfaces.TemplateParser
/**
* 注释
* @author Cold Mint
* @date 2021/12/17 14:55
*/
@ -24,9 +25,11 @@ class IntroducingParser(
LayoutInflater.from(context)
)
override fun getInput(): String {
return ""
}
override val input: String
get() = ""
override val contextView: View
get() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {

View File

@ -18,8 +18,7 @@ class ListParser(val context: Context, val data: ListParserDataBean) : TemplateP
)
private val itemList: List<String> = data.itemList.split(",")
private val dataList: List<String>? = data.dataList?.split(",")
override val input: String
get() {
override fun getInput(): String {
val index = parserListBinding.spacer.selectedItemPosition
return if (dataList != null && dataList.size == itemList.size) {
dataList[index]
@ -28,6 +27,7 @@ class ListParser(val context: Context, val data: ListParserDataBean) : TemplateP
}
}
override val contextView: View
get() {
val adapter =

View File

@ -4,7 +4,9 @@ import android.os.Handler
import android.os.Looper
import android.util.Log
import com.coldmint.rust.core.dataBean.ApiResponse
import com.coldmint.rust.core.dataBean.webTemplate.WebTemplatePackageListData
import com.coldmint.rust.core.dataBean.SubscriptionData
import com.coldmint.rust.core.dataBean.WebTemplatePackageListData
import com.coldmint.rust.core.dataBean.template.WebTemplateData
import com.coldmint.rust.core.interfaces.ApiCallBack
import com.google.gson.Gson
import okhttp3.*
@ -21,57 +23,8 @@ class TemplatePhp {
private constructor()
/**
* 发送错误报告
* @param website 网址(如果程序已崩溃需要重新读取设置的网址)
* @param message String 消息
* @param versionName 版本名
* @param versionNumber 版本号
* @param apiCallBack ApiCallBack<CouponListDataBean>
*/
fun send(
message: String,
versionName: String,
versionNumber: Int,
apiCallBack: ApiCallBack<ApiResponse>, website: String = ServerConfiguration.website
) {
val okHttpClient = ServerConfiguration.initOkHttpClient()
val requestBodyBuilder: FormBody.Builder =
FormBody.Builder().add("message", message).add("versionName", versionName)
.add("versionNumber", versionNumber.toString())
val requestBody = requestBodyBuilder.build()
val request =
Request.Builder()
.url(website + "php/error.php?action=send")
.post(requestBody).build()
val call = okHttpClient.newCall(request)
val handler = Handler(Looper.getMainLooper())
val gson = Gson()
call.enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
e.printStackTrace()
handler.post { apiCallBack.onFailure(e) }
}
override fun onResponse(call: Call, response: Response) {
try {
val data = response.body!!.string()
Log.d("错误反馈数据", data)
val finalApiResponse =
gson.fromJson(data, ApiResponse::class.java)
handler.post {
apiCallBack.onResponse(finalApiResponse)
}
} catch (e: Exception) {
e.printStackTrace()
handler.post {
apiCallBack.onFailure(e)
}
}
}
})
}
/**
*获取公开的模板包列表
@ -118,6 +71,188 @@ class TemplatePhp {
})
}
/**
*获取模板详情
* @param apiCallBack ApiCallBack<CouponListDataBean>
*/
fun getTemplate(
id: String,
apiCallBack: ApiCallBack<WebTemplateData>
) {
val okHttpClient = ServerConfiguration.initOkHttpClient()
val requestBodyBuilder: FormBody.Builder =
FormBody.Builder().add("id", id)
val requestBody = requestBodyBuilder.build()
val request =
Request.Builder()
.url(ServerConfiguration.website + "php/template.php?action=getTemplate")
.post(requestBody).build()
val call = okHttpClient.newCall(request)
val handler = Handler(Looper.getMainLooper())
val gson = Gson()
call.enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
e.printStackTrace()
handler.post { apiCallBack.onFailure(e) }
}
override fun onResponse(call: Call, response: Response) {
try {
val data = response.body!!.string()
Log.d("获取网络模板详情", data)
val finalWebTemplatePackageListData =
gson.fromJson(data, WebTemplateData::class.java)
handler.post {
apiCallBack.onResponse(finalWebTemplatePackageListData)
}
} catch (e: Exception) {
e.printStackTrace()
handler.post {
apiCallBack.onFailure(e)
}
}
}
})
}
/**
*获用户订阅的模板列表
* @param apiCallBack ApiCallBack<SubscriptionData>
*/
fun getSubscriptionDataList(
token: String,
apiCallBack: ApiCallBack<SubscriptionData>
) {
val okHttpClient = ServerConfiguration.initOkHttpClient()
val requestBodyBuilder: FormBody.Builder =
FormBody.Builder().add("token", token)
val requestBody = requestBodyBuilder.build()
val request =
Request.Builder()
.url(ServerConfiguration.website + "php/template.php?action=getSubscriptionData")
.post(requestBody).build()
val call = okHttpClient.newCall(request)
val handler = Handler(Looper.getMainLooper())
val gson = Gson()
call.enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
e.printStackTrace()
handler.post { apiCallBack.onFailure(e) }
}
override fun onResponse(call: Call, response: Response) {
try {
val data = response.body!!.string()
Log.d("获取网络订阅", data)
val finalSubscriptionData =
gson.fromJson(data, SubscriptionData::class.java)
handler.post {
apiCallBack.onResponse(finalSubscriptionData)
}
} catch (e: Exception) {
e.printStackTrace()
handler.post {
apiCallBack.onFailure(e)
}
}
}
})
}
/**
*订阅模板
* @param apiCallBack ApiCallBack<CouponListDataBean>
*/
fun subscription(
token: String,
packageId: String,
apiCallBack: ApiCallBack<ApiResponse>
) {
val okHttpClient = ServerConfiguration.initOkHttpClient()
val requestBodyBuilder: FormBody.Builder =
FormBody.Builder().add("token", token).add("packageId", packageId)
val requestBody = requestBodyBuilder.build()
val request =
Request.Builder()
.url(ServerConfiguration.website + "php/template.php?action=subscription")
.post(requestBody).build()
val call = okHttpClient.newCall(request)
val handler = Handler(Looper.getMainLooper())
val gson = Gson()
call.enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
e.printStackTrace()
handler.post { apiCallBack.onFailure(e) }
}
override fun onResponse(call: Call, response: Response) {
try {
val data = response.body!!.string()
Log.d("订阅模板", data)
val finalApiResponse =
gson.fromJson(data, ApiResponse::class.java)
handler.post {
apiCallBack.onResponse(finalApiResponse)
}
} catch (e: Exception) {
e.printStackTrace()
handler.post {
apiCallBack.onFailure(e)
}
}
}
})
}
/**
*退订模板
* @param apiCallBack ApiCallBack<CouponListDataBean>
*/
fun deleteSubscription(
token: String,
packageId: String,
apiCallBack: ApiCallBack<ApiResponse>
) {
val okHttpClient = ServerConfiguration.initOkHttpClient()
val requestBodyBuilder: FormBody.Builder =
FormBody.Builder().add("token", token).add("packageId", packageId)
val requestBody = requestBodyBuilder.build()
val request =
Request.Builder()
.url(ServerConfiguration.website + "php/template.php?action=deleteSubscription")
.post(requestBody).build()
val call = okHttpClient.newCall(request)
val handler = Handler(Looper.getMainLooper())
val gson = Gson()
call.enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
e.printStackTrace()
handler.post { apiCallBack.onFailure(e) }
}
override fun onResponse(call: Call, response: Response) {
try {
val data = response.body!!.string()
Log.d("退订模板", data)
val finalApiResponse =
gson.fromJson(data, ApiResponse::class.java)
handler.post {
apiCallBack.onResponse(finalApiResponse)
}
} catch (e: Exception) {
e.printStackTrace()
handler.post {
apiCallBack.onFailure(e)
}
}
}
})
}
/**
* 创建模板包
* @param id String 模板包id

View File

@ -24,8 +24,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/title"
android:visibility="gone" />
android:text="@string/title" />
<CheckBox
android:id="@+id/checkbox"
@ -64,6 +63,7 @@
</RelativeLayout>
</LinearLayout>