1.Mod list add sort support

2.Bug fix
3.Minor improvement
This commit is contained in:
ZaneYork 2020-03-21 17:15:27 +08:00
parent 6fdb48cb77
commit c9938c3b8e
18 changed files with 198 additions and 26 deletions

View File

@ -10,8 +10,8 @@ android {
applicationId "com.zane.smapiinstaller"
minSdkVersion 19
targetSdkVersion 28
versionCode 17
versionName "1.3.3"
versionCode 18
versionName "1.3.4"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
multiDexEnabled true

View File

@ -174,10 +174,25 @@ public class MainActivity extends AppCompatActivity {
return true;
}
private int getTranslateServiceIndex(AppConfig selectedTranslator) {
if(selectedTranslator == null) {
return 0;
}
switch (selectedTranslator.getValue()){
case "OFF":
return 0;
case "Google":
return 1;
default:
return 2;
}
}
private void selectTranslateServiceLogic() {
DialogUtils.setCurrentDialog(new MaterialDialog.Builder(this).title(R.string.settings_translation_service).items(R.array.translators).itemsCallback((dialog, itemView, position, text) -> {
DaoSession daoSession = ((MainApplication)this.getApplication()).getDaoSession();
AppConfigDao appConfigDao = daoSession.getAppConfigDao();
DaoSession daoSession = ((MainApplication)this.getApplication()).getDaoSession();
AppConfigDao appConfigDao = daoSession.getAppConfigDao();
int index = getTranslateServiceIndex(appConfigDao.queryBuilder().where(AppConfigDao.Properties.Name.eq(AppConfigKey.ACTIVE_TRANSLATOR)).build().unique());
DialogUtils.setCurrentDialog(new MaterialDialog.Builder(this).title(R.string.settings_translation_service).items(R.array.translators).itemsCallbackSingleChoice(index, (dialog, itemView, position, text) -> {
AppConfig activeTranslator = appConfigDao.queryBuilder().where(AppConfigDao.Properties.Name.eq(AppConfigKey.ACTIVE_TRANSLATOR)).build().unique();
switch (position) {
case 0:
@ -202,8 +217,9 @@ public class MainActivity extends AppCompatActivity {
appConfigDao.insertOrReplace(activeTranslator);
break;
default:
break;
return false;
}
return true;
}).show());
}

View File

@ -2,4 +2,6 @@ package com.zane.smapiinstaller.constant;
public class AppConfigKey {
public static final String ACTIVE_TRANSLATOR = "ActiveTranslator";
public static final String MOD_LIST_SORT_BY = "ModListSortBy";
}

View File

@ -1,5 +1,6 @@
package com.zane.smapiinstaller.entity;
import java.util.Date;
import java.util.Set;
import lombok.Data;
@ -51,4 +52,8 @@ public class ModManifestEntry {
* 翻译后的Description
*/
private transient String translatedDescription;
/**
* 文件修改日期
*/
private transient Long lastModified;
}

View File

@ -111,6 +111,7 @@ public class ModAssetsManager {
break;
}
manifest.setAssetPath(file.getParentFile().getAbsolutePath());
manifest.setLastModified(file.lastModified());
mods.add(manifest);
}
break;

View File

@ -15,7 +15,12 @@ import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.OnTextChanged;
import com.afollestad.materialdialogs.MaterialDialog;
import com.google.common.collect.Lists;
import com.zane.smapiinstaller.R;
import com.zane.smapiinstaller.utils.DialogUtils;
import java.util.ArrayList;
public class ConfigFragment extends Fragment {
@ -30,17 +35,58 @@ public class ConfigFragment extends Fragment {
ButterKnife.bind(this, root);
recyclerView.setLayoutManager(new LinearLayoutManager(this.getContext()));
configViewModel = new ConfigViewModel(root);
ModManifestAdapter modManifestAdapter = new ModManifestAdapter(configViewModel, configViewModel.getModList());
ModManifestAdapter modManifestAdapter = new ModManifestAdapter(configViewModel, new ArrayList<>(configViewModel.getModList()));
recyclerView.setAdapter(modManifestAdapter);
configViewModel.registerListChangeListener((list) -> {
modManifestAdapter.setList(list);
modManifestAdapter.setList(new ArrayList<>(list));
return true;
});
recyclerView.addItemDecoration(new DividerItemDecoration(recyclerView.getContext(), DividerItemDecoration.VERTICAL));
return root;
}
@OnTextChanged(R.id.button_search) void onSearchMod(CharSequence text){
@OnTextChanged(R.id.button_search)
void onSearchMod(CharSequence text) {
configViewModel.filter(text);
}
@OnClick(R.id.button_sort_by)
void onSortByClick() {
int index;
switch (configViewModel.getSortBy()){
case "Name asc":
index = 0;
break;
case "Name desc":
index = 1;
break;
case "Date asc":
index = 2;
break;
case "Date desc":
index = 3;
break;
default:
index = 0;
}
DialogUtils.setCurrentDialog(new MaterialDialog.Builder(this.getContext()).title(R.string.sort_by).items(R.array.mod_list_sort_by).itemsCallbackSingleChoice(index, (dialog, itemView, position, text) -> {
switch (position) {
case 0:
configViewModel.switchSortBy("Name asc");
break;
case 1:
configViewModel.switchSortBy("Name desc");
break;
case 2:
configViewModel.switchSortBy("Date asc");
break;
case 3:
configViewModel.switchSortBy("Date desc");
break;
default:
return false;
}
return true;
}).show());
}
}

View File

@ -37,19 +37,79 @@ class ConfigViewModel extends ViewModel {
private List<ModManifestEntry> modList;
private List<ModManifestEntry> filteredModList;
private String sortBy = "Name asc";
public String getSortBy() {
return sortBy;
}
private View root;
private List<Predicate<List<ModManifestEntry>>> onChangedListener = new ArrayList<>();
ConfigViewModel(View root) {
this.root = root;
this.modList = ModAssetsManager.findAllInstalledMods();
translateLogic(root);
Collections.sort(this.modList, (a, b) -> {
if (a.getContentPackFor() != null && b.getContentPackFor() == null) {
return 1;
} else if (b.getContentPackFor() != null) {
return -1;
MainApplication app = CommonLogic.getApplicationFromView(root);
if (null != app) {
AppConfigDao appConfigDao = app.getDaoSession().getAppConfigDao();
Query<AppConfig> query = appConfigDao.queryBuilder().where(AppConfigDao.Properties.Name.eq(AppConfigKey.MOD_LIST_SORT_BY)).build();
AppConfig appConfig = query.unique();
if(null != appConfig) {
sortBy = appConfig.getValue();
}
return a.getName().compareTo(b.getName());
});
}
sortLogic(sortBy);
}
public void switchSortBy(String sortBy) {
MainApplication app = CommonLogic.getApplicationFromView(root);
if(null == app) {
return;
}
this.sortBy = sortBy;
AppConfigDao appConfigDao = app.getDaoSession().getAppConfigDao();
AppConfig appConfig = new AppConfig(null, AppConfigKey.MOD_LIST_SORT_BY, sortBy);
appConfigDao.insertOrReplace(appConfig);
sortLogic(appConfig.getValue());
}
private void sortLogic(String sortBy) {
switch (sortBy) {
case "Name asc":
Collections.sort(modList, (a, b) -> a.getName().compareTo(b.getName()));
if(filteredModList != null && filteredModList != modList) {
Collections.sort(filteredModList, (a, b) -> a.getName().compareTo(b.getName()));
}
break;
case "Name desc":
Collections.sort(modList, (a, b) -> b.getName().compareTo(a.getName()));
if(filteredModList != null && filteredModList != modList) {
Collections.sort(filteredModList, (a, b) -> b.getName().compareTo(a.getName()));
}
break;
case "Date asc":
Collections.sort(modList, (a, b) -> a.getLastModified().compareTo(b.getLastModified()));
if(filteredModList != null && filteredModList != modList) {
Collections.sort(filteredModList, (a, b) -> a.getLastModified().compareTo(b.getLastModified()));
}
break;
case "Date desc":
Collections.sort(modList, (a, b) -> b.getLastModified().compareTo(a.getLastModified()));
if(filteredModList != null && filteredModList != modList) {
Collections.sort(filteredModList, (a, b) -> b.getLastModified().compareTo(a.getLastModified()));
}
break;
default:
return;
}
for (Predicate<List<ModManifestEntry>> listener : onChangedListener) {
if(filteredModList != null){
listener.apply(filteredModList);
}
else {
listener.apply(modList);
}
}
}
private void translateLogic(View root) {
@ -57,7 +117,7 @@ class ConfigViewModel extends ViewModel {
if (null != app) {
DaoSession daoSession = app.getDaoSession();
AppConfig activeTranslator = daoSession.getAppConfigDao().queryBuilder().where(AppConfigDao.Properties.Name.eq(AppConfigKey.ACTIVE_TRANSLATOR)).build().unique();
if(activeTranslator != null) {
if (activeTranslator != null) {
String translator = activeTranslator.getValue();
ArrayList<String> descriptions = Lists.newArrayList(Iterables.filter(Iterables.transform(this.modList, ModManifestEntry::getDescription), item -> item != null));
String language = LanguagesManager.getAppLanguage(app).getLanguage();
@ -119,18 +179,16 @@ class ConfigViewModel extends ViewModel {
}
public void filter(CharSequence text) {
if(StringUtils.isBlank(text)) {
if (StringUtils.isBlank(text)) {
filteredModList = modList;
}
else {
} else {
filteredModList = Lists.newArrayList(Iterables.filter(modList, mod -> {
if(StringUtils.containsIgnoreCase(mod.getName(), text)) {
if (StringUtils.containsIgnoreCase(mod.getName(), text)) {
return true;
}
if(StringUtils.isNoneBlank(mod.getTranslatedDescription())){
if (StringUtils.isNoneBlank(mod.getTranslatedDescription())) {
return StringUtils.containsIgnoreCase(mod.getTranslatedDescription(), text);
}
else {
} else {
return StringUtils.containsIgnoreCase(mod.getDescription(), text);
}
}));

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -11,11 +11,20 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="@id/guideline_v1"
app:layout_constraintEnd_toStartOf="@id/guideline_v2"
app:layout_constraintEnd_toStartOf="@id/guideline_v3"
app:layout_constraintTop_toBottomOf="@id/guideline_h1"
android:hint="@android:string/search_go"
android:inputType="text"
android:importantForAutofill="no"/>
<Button
android:id="@+id/button_sort_by"
android:layout_width="32dp"
android:layout_height="32dp"
android:background="@drawable/sort_by"
app:layout_constraintStart_toEndOf="@id/button_search"
app:layout_constraintEnd_toStartOf="@id/guideline_v2"
app:layout_constraintTop_toTopOf="@id/button_search"
app:layout_constraintBottom_toBottomOf="@id/button_search" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/view_mod_list"
@ -54,4 +63,11 @@
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_end="10dp" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_v3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_end="42dp" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -61,7 +61,7 @@
<string name="settings_verbose_logging">Catatan Terperinci</string>
<string name="signing_package">Menandatangani</string>
<string name="smapi_game_name">SMAPI Stardew Valley</string>
<string name="smapi_version">Versi SMAPI: 3.3.2.3</string>
<string name="smapi_version">Versi SMAPI: 3.3.2.4</string>
<string name="text_install_tip1">Catatan: Dibutuhkan Stardew Valley versi 1.4.5.138 atau yang lebih baru.</string>
<string name="text_install_tip2">Permainan dasar diperlukan saat memperbarui/menginstal.</string>
<string name="unpacking_smapi_files">Membongkar</string>

View File

@ -23,4 +23,10 @@
<item>谷歌</item>
<item>有道</item>
</string-array>
<string-array name="mod_list_sort_by">
<item>名稱(正序)</item>
<item>名稱(倒序)</item>
<item>日期(正序)</item>
<item>日期(倒序)</item>
</string-array>
</resources>

View File

@ -64,4 +64,5 @@
<string name="text_install_tip1">注意需要不低於1.4.5.138版本的遊戲本體</string>
<string name="text_install_tip2">更新或安裝期間需要安裝遊戲本體</string>
<string name="unpacking_smapi_files">正在解包</string>
<string name="sort_by">排序方式</string>
</resources>

View File

@ -23,4 +23,10 @@
<item>谷歌</item>
<item>有道</item>
</string-array>
<string-array name="mod_list_sort_by">
<item>名稱(正序)</item>
<item>名稱(倒序)</item>
<item>日期(正序)</item>
<item>日期(倒序)</item>
</string-array>
</resources>

View File

@ -64,4 +64,5 @@
<string name="text_install_tip1">注意需要不低於1.4.5.138版本的遊戲本體</string>
<string name="text_install_tip2">更新或安裝期間需要安裝遊戲本體</string>
<string name="unpacking_smapi_files">正在解包</string>
<string name="sort_by">排序方式</string>
</resources>

View File

@ -23,4 +23,10 @@
<item>谷歌</item>
<item>有道</item>
</string-array>
<string-array name="mod_list_sort_by">
<item>名称(正序)</item>
<item>名称(倒序)</item>
<item>日期(正序)</item>
<item>日期(倒序)</item>
</string-array>
</resources>

View File

@ -64,4 +64,5 @@
<string name="text_install_tip1">注意需要不低于1.4.5.138版本的游戏本体</string>
<string name="text_install_tip2">更新或安装期间需要安装游戏本体</string>
<string name="unpacking_smapi_files">正在解包</string>
<string name="sort_by">排序方式</string>
</resources>

View File

@ -23,4 +23,10 @@
<item>Google</item>
<item>YouDao</item>
</string-array>
<string-array name="mod_list_sort_by">
<item>by Name(asc)</item>
<item>by Name(desc)</item>
<item>by Date(asc)</item>
<item>by Date(desc)</item>
</string-array>
</resources>

View File

@ -67,4 +67,5 @@
<string name="toast_redpacket_message" translatable="false">红包码已复制\n支付宝首页搜索“9188262” 立即领红包</string>
<string name="icon_desc" translatable="false">icon</string>
<string name="sort_by">Sort by</string>
</resources>