mirror of
https://github.com/AngelAuraMC/Amethyst-Android.git
synced 2025-09-14 23:28:52 -04:00
Feat[modpack]: disable the "Install" button when tasks are ongoing
This commit is contained in:
parent
d00565ebac
commit
e513156c6f
@ -1,12 +1,9 @@
|
|||||||
package net.kdt.pojavlaunch.fragments;
|
package net.kdt.pojavlaunch.fragments;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.res.ColorStateList;
|
import android.content.res.ColorStateList;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
@ -28,6 +25,7 @@ import net.kdt.pojavlaunch.modloaders.modpacks.api.CommonApi;
|
|||||||
import net.kdt.pojavlaunch.modloaders.modpacks.api.ModpackApi;
|
import net.kdt.pojavlaunch.modloaders.modpacks.api.ModpackApi;
|
||||||
import net.kdt.pojavlaunch.modloaders.modpacks.models.SearchFilters;
|
import net.kdt.pojavlaunch.modloaders.modpacks.models.SearchFilters;
|
||||||
import net.kdt.pojavlaunch.profiles.VersionSelectorDialog;
|
import net.kdt.pojavlaunch.profiles.VersionSelectorDialog;
|
||||||
|
import net.kdt.pojavlaunch.progresskeeper.ProgressKeeper;
|
||||||
|
|
||||||
public class SearchModFragment extends Fragment implements ModItemAdapter.SearchResultCallback {
|
public class SearchModFragment extends Fragment implements ModItemAdapter.SearchResultCallback {
|
||||||
|
|
||||||
@ -70,6 +68,7 @@ public class SearchModFragment extends Fragment implements ModItemAdapter.Search
|
|||||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
// You can only access resources after attaching to current context
|
// You can only access resources after attaching to current context
|
||||||
mModItemAdapter = new ModItemAdapter(getResources(), modpackApi, this);
|
mModItemAdapter = new ModItemAdapter(getResources(), modpackApi, this);
|
||||||
|
ProgressKeeper.addTaskCountListener(mModItemAdapter);
|
||||||
mOverlayTopCache = getResources().getDimension(R.dimen.fragment_padding_medium);
|
mOverlayTopCache = getResources().getDimension(R.dimen.fragment_padding_medium);
|
||||||
|
|
||||||
mOverlay = view.findViewById(R.id.search_mod_overlay);
|
mOverlay = view.findViewById(R.id.search_mod_overlay);
|
||||||
@ -106,6 +105,7 @@ public class SearchModFragment extends Fragment implements ModItemAdapter.Search
|
|||||||
@Override
|
@Override
|
||||||
public void onDestroyView() {
|
public void onDestroyView() {
|
||||||
super.onDestroyView();
|
super.onDestroyView();
|
||||||
|
ProgressKeeper.removeTaskCountListener(mModItemAdapter);
|
||||||
mRecyclerview.removeOnScrollListener(mOverlayPositionListener);
|
mRecyclerview.removeOnScrollListener(mOverlayPositionListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,6 +142,10 @@ public class SearchModFragment extends Fragment implements ModItemAdapter.Search
|
|||||||
Button mSelectVersionButton = dialog.findViewById(R.id.search_mod_mc_version_button);
|
Button mSelectVersionButton = dialog.findViewById(R.id.search_mod_mc_version_button);
|
||||||
Button mApplyButton = dialog.findViewById(R.id.search_mod_apply_filters);
|
Button mApplyButton = dialog.findViewById(R.id.search_mod_apply_filters);
|
||||||
|
|
||||||
|
assert mSelectVersionButton != null;
|
||||||
|
assert mSelectedVersion != null;
|
||||||
|
assert mApplyButton != null;
|
||||||
|
|
||||||
// Setup the expendable list behavior
|
// Setup the expendable list behavior
|
||||||
mSelectVersionButton.setOnClickListener(v -> VersionSelectorDialog.open(v.getContext(), true, (id, snapshot)-> mSelectedVersion.setText(id)));
|
mSelectVersionButton.setOnClickListener(v -> VersionSelectorDialog.open(v.getContext(), true, (id, snapshot)-> mSelectedVersion.setText(id)));
|
||||||
|
|
||||||
|
@ -31,18 +31,23 @@ import net.kdt.pojavlaunch.modloaders.modpacks.models.ModDetail;
|
|||||||
import net.kdt.pojavlaunch.modloaders.modpacks.models.ModItem;
|
import net.kdt.pojavlaunch.modloaders.modpacks.models.ModItem;
|
||||||
import net.kdt.pojavlaunch.modloaders.modpacks.models.SearchFilters;
|
import net.kdt.pojavlaunch.modloaders.modpacks.models.SearchFilters;
|
||||||
import net.kdt.pojavlaunch.modloaders.modpacks.models.SearchResult;
|
import net.kdt.pojavlaunch.modloaders.modpacks.models.SearchResult;
|
||||||
|
import net.kdt.pojavlaunch.progresskeeper.TaskCountListener;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.WeakHashMap;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
public class ModItemAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
public class ModItemAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements TaskCountListener {
|
||||||
private static final ModItem[] MOD_ITEMS_EMPTY = new ModItem[0];
|
private static final ModItem[] MOD_ITEMS_EMPTY = new ModItem[0];
|
||||||
private static final int VIEW_TYPE_MOD_ITEM = 0;
|
private static final int VIEW_TYPE_MOD_ITEM = 0;
|
||||||
private static final int VIEW_TYPE_LOADING = 1;
|
private static final int VIEW_TYPE_LOADING = 1;
|
||||||
|
|
||||||
/* Used when versions haven't loaded yet, default text to reduce layout shifting */
|
/* Used when versions haven't loaded yet, default text to reduce layout shifting */
|
||||||
private final SimpleArrayAdapter<String> mLoadingAdapter = new SimpleArrayAdapter<>(Collections.singletonList("Loading"));
|
private final SimpleArrayAdapter<String> mLoadingAdapter = new SimpleArrayAdapter<>(Collections.singletonList("Loading"));
|
||||||
|
/* This my seem horribly inefficient but it is in fact the most efficient way without effectively writing a weak collection from scratch */
|
||||||
|
private final Set<ViewHolder> mViewHolderSet = Collections.newSetFromMap(new WeakHashMap<>());
|
||||||
private final ModIconCache mIconCache = new ModIconCache();
|
private final ModIconCache mIconCache = new ModIconCache();
|
||||||
private final SearchResultCallback mSearchResultCallback;
|
private final SearchResultCallback mSearchResultCallback;
|
||||||
private ModItem[] mModItems;
|
private ModItem[] mModItems;
|
||||||
@ -55,6 +60,7 @@ public class ModItemAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||||||
private SearchFilters mSearchFilters;
|
private SearchFilters mSearchFilters;
|
||||||
private SearchResult mCurrentResult;
|
private SearchResult mCurrentResult;
|
||||||
private boolean mLastPage;
|
private boolean mLastPage;
|
||||||
|
private boolean mTasksRunning;
|
||||||
|
|
||||||
|
|
||||||
public ModItemAdapter(Resources resources, ModpackApi api, SearchResultCallback callback) {
|
public ModItemAdapter(Resources resources, ModpackApi api, SearchResultCallback callback) {
|
||||||
@ -126,6 +132,15 @@ public class ModItemAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||||||
return VIEW_TYPE_LOADING;
|
return VIEW_TYPE_LOADING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUpdateTaskCount(int taskCount) {
|
||||||
|
Tools.runOnUiThread(()->{
|
||||||
|
mTasksRunning = taskCount != 0;
|
||||||
|
for(ViewHolder viewHolder : mViewHolderSet) {
|
||||||
|
viewHolder.updateInstallButtonState();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -144,13 +159,14 @@ public class ModItemAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||||||
private Future<?> mExtensionFuture;
|
private Future<?> mExtensionFuture;
|
||||||
private Bitmap mThumbnailBitmap;
|
private Bitmap mThumbnailBitmap;
|
||||||
private ImageReceiver mImageReceiver;
|
private ImageReceiver mImageReceiver;
|
||||||
|
private boolean mInstallEnabled;
|
||||||
|
|
||||||
/* Used to display available versions of the mod(pack) */
|
/* Used to display available versions of the mod(pack) */
|
||||||
private final SimpleArrayAdapter<String> mVersionAdapter = new SimpleArrayAdapter<>(null);
|
private final SimpleArrayAdapter<String> mVersionAdapter = new SimpleArrayAdapter<>(null);
|
||||||
|
|
||||||
public ViewHolder(View view) {
|
public ViewHolder(View view) {
|
||||||
super(view);
|
super(view);
|
||||||
|
mViewHolderSet.add(this);
|
||||||
view.setOnClickListener(v -> {
|
view.setOnClickListener(v -> {
|
||||||
if(!hasExtended()){
|
if(!hasExtended()){
|
||||||
// Inflate the ViewStub
|
// Inflate the ViewStub
|
||||||
@ -252,15 +268,14 @@ public class ModItemAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||||||
|
|
||||||
/** Display extended info/interaction about a modpack */
|
/** Display extended info/interaction about a modpack */
|
||||||
private void setStateDetailed(ModDetail detailedItem) {
|
private void setStateDetailed(ModDetail detailedItem) {
|
||||||
|
|
||||||
if(detailedItem != null) {
|
if(detailedItem != null) {
|
||||||
mExtendedButton.setEnabled(true);
|
setInstallEnabled(true);
|
||||||
mExtendedErrorTextView.setVisibility(View.GONE);
|
mExtendedErrorTextView.setVisibility(View.GONE);
|
||||||
mVersionAdapter.setObjects(Arrays.asList(detailedItem.versionNames));
|
mVersionAdapter.setObjects(Arrays.asList(detailedItem.versionNames));
|
||||||
mExtendedSpinner.setAdapter(mVersionAdapter);
|
mExtendedSpinner.setAdapter(mVersionAdapter);
|
||||||
} else {
|
} else {
|
||||||
closeDetailedView();
|
closeDetailedView();
|
||||||
mExtendedButton.setEnabled(false);
|
setInstallEnabled(false);
|
||||||
mExtendedErrorTextView.setVisibility(View.VISIBLE);
|
mExtendedErrorTextView.setVisibility(View.VISIBLE);
|
||||||
mExtendedSpinner.setAdapter(null);
|
mExtendedSpinner.setAdapter(null);
|
||||||
mVersionAdapter.setObjects(null);
|
mVersionAdapter.setObjects(null);
|
||||||
@ -284,7 +299,7 @@ public class ModItemAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setDetailedStateDefault() {
|
private void setDetailedStateDefault() {
|
||||||
mExtendedButton.setEnabled(false);
|
setInstallEnabled(false);
|
||||||
mExtendedSpinner.setAdapter(mLoadingAdapter);
|
mExtendedSpinner.setAdapter(mLoadingAdapter);
|
||||||
mExtendedErrorTextView.setVisibility(View.GONE);
|
mExtendedErrorTextView.setVisibility(View.GONE);
|
||||||
openDetailedView();
|
openDetailedView();
|
||||||
@ -308,6 +323,16 @@ public class ModItemAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
|||||||
throw new RuntimeException("Unknown API source");
|
throw new RuntimeException("Unknown API source");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setInstallEnabled(boolean enabled) {
|
||||||
|
mInstallEnabled = enabled;
|
||||||
|
updateInstallButtonState();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateInstallButtonState() {
|
||||||
|
if(mExtendedButton != null)
|
||||||
|
mExtendedButton.setEnabled(mInstallEnabled && !mTasksRunning);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2,18 +2,16 @@ package net.kdt.pojavlaunch.modloaders.modpacks.api;
|
|||||||
|
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
|
||||||
import android.widget.Toast;
|
import com.kdt.mcgui.ProgressLayout;
|
||||||
|
|
||||||
import net.kdt.pojavlaunch.PojavApplication;
|
import net.kdt.pojavlaunch.PojavApplication;
|
||||||
import net.kdt.pojavlaunch.modloaders.ModloaderDownloadListener;
|
import net.kdt.pojavlaunch.R;
|
||||||
import net.kdt.pojavlaunch.modloaders.modpacks.models.ModDetail;
|
import net.kdt.pojavlaunch.modloaders.modpacks.models.ModDetail;
|
||||||
import net.kdt.pojavlaunch.modloaders.modpacks.models.ModItem;
|
import net.kdt.pojavlaunch.modloaders.modpacks.models.ModItem;
|
||||||
import net.kdt.pojavlaunch.modloaders.modpacks.models.SearchFilters;
|
import net.kdt.pojavlaunch.modloaders.modpacks.models.SearchFilters;
|
||||||
import net.kdt.pojavlaunch.modloaders.modpacks.models.SearchResult;
|
import net.kdt.pojavlaunch.modloaders.modpacks.models.SearchResult;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -21,7 +19,7 @@ public interface ModpackApi {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param searchFilters Filters
|
* @param searchFilters Filters
|
||||||
* @param previousPageResult
|
* @param previousPageResult The result from the previous page
|
||||||
* @return the list of mod items from specified offset
|
* @return the list of mod items from specified offset
|
||||||
*/
|
*/
|
||||||
SearchResult searchMod(SearchFilters searchFilters, SearchResult previousPageResult);
|
SearchResult searchMod(SearchFilters searchFilters, SearchResult previousPageResult);
|
||||||
@ -47,6 +45,9 @@ public interface ModpackApi {
|
|||||||
* @param selectedVersion The selected version
|
* @param selectedVersion The selected version
|
||||||
*/
|
*/
|
||||||
default void handleInstallation(Context context, ModDetail modDetail, int selectedVersion) {
|
default void handleInstallation(Context context, ModDetail modDetail, int selectedVersion) {
|
||||||
|
// Doing this here since when starting installation, the progress does not start immediately
|
||||||
|
// which may lead to two concurrent installations (very bad)
|
||||||
|
ProgressLayout.setProgress(ProgressLayout.INSTALL_MODPACK, 0, R.string.global_waiting);
|
||||||
PojavApplication.sExecutorService.execute(() -> {
|
PojavApplication.sExecutorService.execute(() -> {
|
||||||
ModLoader loaderInfo = installMod(modDetail, selectedVersion);
|
ModLoader loaderInfo = installMod(modDetail, selectedVersion);
|
||||||
if (loaderInfo == null) return;
|
if (loaderInfo == null) return;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user