mirror of
https://github.com/AngelAuraMC/Amethyst-Android.git
synced 2025-09-15 15:48:26 -04:00
Multiple things
- Add Fabric installer - Make both installers Fragments - Add new Tools methods (and move some existing code to use them)
This commit is contained in:
parent
df1b52adb7
commit
d5935be9aa
@ -4,8 +4,6 @@ import android.app.Activity;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Looper;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
@ -89,7 +87,7 @@ public class ImportControlActivity extends Activity {
|
|||||||
}).start();
|
}).start();
|
||||||
|
|
||||||
//Auto show the keyboard
|
//Auto show the keyboard
|
||||||
new Handler(Looper.getMainLooper()).postDelayed(() -> {
|
Tools.MAIN_HANDLER.postDelayed(() -> {
|
||||||
InputMethodManager imm = (InputMethodManager) getApplicationContext().getSystemService(INPUT_METHOD_SERVICE);
|
InputMethodManager imm = (InputMethodManager) getApplicationContext().getSystemService(INPUT_METHOD_SERVICE);
|
||||||
imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);
|
imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);
|
||||||
mEditText.setSelection(mEditText.getText().length());
|
mEditText.setSelection(mEditText.getText().length());
|
||||||
|
@ -153,6 +153,7 @@ public class JavaGUILauncherActivity extends BaseActivity implements View.OnTouc
|
|||||||
final Runtime runtime = MultiRTUtils.forceReread(jreName);
|
final Runtime runtime = MultiRTUtils.forceReread(jreName);
|
||||||
|
|
||||||
mSkipDetectMod = getIntent().getExtras().getBoolean("skipDetectMod", false);
|
mSkipDetectMod = getIntent().getExtras().getBoolean("skipDetectMod", false);
|
||||||
|
if(getIntent().getExtras().getBoolean("openLogOutput", false)) openLogOutput(null);
|
||||||
if (mSkipDetectMod) {
|
if (mSkipDetectMod) {
|
||||||
new Thread(() -> launchJavaRuntime(runtime, modFile, javaArgs), "JREMainThread").start();
|
new Thread(() -> launchJavaRuntime(runtime, modFile, javaArgs), "JREMainThread").start();
|
||||||
return;
|
return;
|
||||||
|
@ -21,8 +21,6 @@ import android.graphics.drawable.ColorDrawable;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Looper;
|
|
||||||
import android.provider.DocumentsContract;
|
import android.provider.DocumentsContract;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
@ -287,7 +285,7 @@ public class MainActivity extends BaseActivity implements ControlButtonMenuListe
|
|||||||
protected void onPostResume() {
|
protected void onPostResume() {
|
||||||
super.onPostResume();
|
super.onPostResume();
|
||||||
if(minecraftGLView != null) // Useful when backing out of the app
|
if(minecraftGLView != null) // Useful when backing out of the app
|
||||||
new Handler(Looper.getMainLooper()).postDelayed(() -> minecraftGLView.refreshSize(), 500);
|
Tools.MAIN_HANDLER.postDelayed(() -> minecraftGLView.refreshSize(), 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -22,6 +22,8 @@ import android.net.Uri;
|
|||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
import android.provider.DocumentsContract;
|
import android.provider.DocumentsContract;
|
||||||
import android.provider.OpenableColumns;
|
import android.provider.OpenableColumns;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
@ -77,6 +79,7 @@ import java.util.Map;
|
|||||||
|
|
||||||
@SuppressWarnings("IOStreamConstructor")
|
@SuppressWarnings("IOStreamConstructor")
|
||||||
public final class Tools {
|
public final class Tools {
|
||||||
|
public static final Handler MAIN_HANDLER = new Handler(Looper.getMainLooper());
|
||||||
public static String APP_NAME = "null";
|
public static String APP_NAME = "null";
|
||||||
|
|
||||||
public static final Gson GLOBAL_GSON = new GsonBuilder().setPrettyPrinting().create();
|
public static final Gson GLOBAL_GSON = new GsonBuilder().setPrettyPrinting().create();
|
||||||
@ -959,6 +962,10 @@ public final class Tools {
|
|||||||
return runtime;
|
return runtime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void runOnUiThread(Runnable runnable) {
|
||||||
|
MAIN_HANDLER.post(runnable);
|
||||||
|
}
|
||||||
|
|
||||||
public static @NonNull String pickRuntime(MinecraftProfile minecraftProfile, int targetJavaVersion) {
|
public static @NonNull String pickRuntime(MinecraftProfile minecraftProfile, int targetJavaVersion) {
|
||||||
String runtime = getSelectedRuntime(minecraftProfile);
|
String runtime = getSelectedRuntime(minecraftProfile);
|
||||||
String profileRuntime = getRuntimeName(minecraftProfile.javaDir);
|
String profileRuntime = getRuntimeName(minecraftProfile.javaDir);
|
||||||
|
@ -2,7 +2,6 @@ package net.kdt.pojavlaunch.authenticator.microsoft;
|
|||||||
|
|
||||||
import static net.kdt.pojavlaunch.PojavApplication.sExecutorService;
|
import static net.kdt.pojavlaunch.PojavApplication.sExecutorService;
|
||||||
|
|
||||||
import android.os.Looper;
|
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
@ -13,8 +12,10 @@ import com.kdt.mcgui.ProgressLayout;
|
|||||||
|
|
||||||
import net.kdt.pojavlaunch.R;
|
import net.kdt.pojavlaunch.R;
|
||||||
import net.kdt.pojavlaunch.Tools;
|
import net.kdt.pojavlaunch.Tools;
|
||||||
|
import net.kdt.pojavlaunch.authenticator.listener.DoneListener;
|
||||||
|
import net.kdt.pojavlaunch.authenticator.listener.ErrorListener;
|
||||||
|
import net.kdt.pojavlaunch.authenticator.listener.ProgressListener;
|
||||||
import net.kdt.pojavlaunch.value.MinecraftAccount;
|
import net.kdt.pojavlaunch.value.MinecraftAccount;
|
||||||
import net.kdt.pojavlaunch.authenticator.listener.*;
|
|
||||||
|
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
@ -42,7 +43,6 @@ public class MicrosoftBackgroundLogin {
|
|||||||
|
|
||||||
private final boolean mIsRefresh;
|
private final boolean mIsRefresh;
|
||||||
private final String mAuthCode;
|
private final String mAuthCode;
|
||||||
private final android.os.Handler mHandler = new android.os.Handler(Looper.getMainLooper());
|
|
||||||
private static final Map<Long, Integer> XSTS_ERRORS;
|
private static final Map<Long, Integer> XSTS_ERRORS;
|
||||||
static {
|
static {
|
||||||
XSTS_ERRORS = new ArrayMap<>();
|
XSTS_ERRORS = new ArrayMap<>();
|
||||||
@ -100,13 +100,13 @@ public class MicrosoftBackgroundLogin {
|
|||||||
|
|
||||||
if(doneListener != null) {
|
if(doneListener != null) {
|
||||||
MinecraftAccount finalAcc = acc;
|
MinecraftAccount finalAcc = acc;
|
||||||
mHandler.post(() -> doneListener.onLoginDone(finalAcc));
|
Tools.runOnUiThread(() -> doneListener.onLoginDone(finalAcc));
|
||||||
}
|
}
|
||||||
|
|
||||||
}catch (Exception e){
|
}catch (Exception e){
|
||||||
Log.e("MicroAuth", e.toString());
|
Log.e("MicroAuth", e.toString());
|
||||||
if(errorListener != null)
|
if(errorListener != null)
|
||||||
mHandler.post(() -> errorListener.onLoginError(e));
|
Tools.runOnUiThread(() -> errorListener.onLoginError(e));
|
||||||
}
|
}
|
||||||
ProgressLayout.clearProgress(ProgressLayout.AUTHENTICATE_MICROSOFT);
|
ProgressLayout.clearProgress(ProgressLayout.AUTHENTICATE_MICROSOFT);
|
||||||
});
|
});
|
||||||
@ -289,7 +289,7 @@ public class MicrosoftBackgroundLogin {
|
|||||||
/** Wrapper to ease notifying the listener */
|
/** Wrapper to ease notifying the listener */
|
||||||
private void notifyProgress(@Nullable ProgressListener listener, int step){
|
private void notifyProgress(@Nullable ProgressListener listener, int step){
|
||||||
if(listener != null){
|
if(listener != null){
|
||||||
mHandler.post(() -> listener.onLoginProgress(step));
|
Tools.runOnUiThread(() -> listener.onLoginProgress(step));
|
||||||
}
|
}
|
||||||
ProgressLayout.setProgress(ProgressLayout.AUTHENTICATE_MICROSOFT, step*20);
|
ProgressLayout.setProgress(ProgressLayout.AUTHENTICATE_MICROSOFT, step*20);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,180 @@
|
|||||||
|
package net.kdt.pojavlaunch.fragments;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Adapter;
|
||||||
|
import android.widget.AdapterView;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
|
import android.widget.Spinner;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
||||||
|
import net.kdt.pojavlaunch.JavaGUILauncherActivity;
|
||||||
|
import net.kdt.pojavlaunch.R;
|
||||||
|
import net.kdt.pojavlaunch.Tools;
|
||||||
|
import net.kdt.pojavlaunch.modloaders.FabricDownloadTask;
|
||||||
|
import net.kdt.pojavlaunch.modloaders.FabricUtils;
|
||||||
|
import net.kdt.pojavlaunch.modloaders.ModloaderDownloadListener;
|
||||||
|
import net.kdt.pojavlaunch.modloaders.ModloaderListenerProxy;
|
||||||
|
import net.kdt.pojavlaunch.profiles.VersionSelectorDialog;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class FabricInstallFragment extends Fragment implements AdapterView.OnItemSelectedListener, ModloaderDownloadListener, Runnable {
|
||||||
|
public static final String TAG = "FabricInstallTarget";
|
||||||
|
private static ModloaderListenerProxy sTaskProxy;
|
||||||
|
private TextView mSelectedVersionLabel;
|
||||||
|
private String mSelectedLoaderVersion;
|
||||||
|
private Spinner mLoaderVersionSpinner;
|
||||||
|
private String mSelectedGameVersion;
|
||||||
|
private boolean mSelectedSnapshot;
|
||||||
|
private ProgressBar mProgressBar;
|
||||||
|
private File mDestinationDir;
|
||||||
|
private Button mStartButton;
|
||||||
|
private View mRetryView;
|
||||||
|
public FabricInstallFragment() {
|
||||||
|
super(R.layout.fragment_fabric_install);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(@NonNull Context context) {
|
||||||
|
super.onAttach(context);
|
||||||
|
this.mDestinationDir = new File(context.getCacheDir(), "fabric-installer");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
mStartButton = view.findViewById(R.id.fabric_installer_start_button);
|
||||||
|
mStartButton.setOnClickListener(this::onClickStart);
|
||||||
|
mSelectedVersionLabel = view.findViewById(R.id.fabric_installer_version_select_label);
|
||||||
|
view.findViewById(R.id.fabric_installer_game_version_change).setOnClickListener(this::onClickSelect);
|
||||||
|
mLoaderVersionSpinner = view.findViewById(R.id.fabric_installer_loader_ver_spinner);
|
||||||
|
mLoaderVersionSpinner.setOnItemSelectedListener(this);
|
||||||
|
mProgressBar = view.findViewById(R.id.fabric_installer_progress_bar);
|
||||||
|
mRetryView = view.findViewById(R.id.fabric_installer_retry_layout);
|
||||||
|
view.findViewById(R.id.fabric_installer_retry_button).setOnClickListener(this::onClickRetry);
|
||||||
|
if(sTaskProxy != null) {
|
||||||
|
mStartButton.setEnabled(false);
|
||||||
|
sTaskProxy.attachListener(this);
|
||||||
|
}
|
||||||
|
new Thread(this).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroyView() {
|
||||||
|
super.onDestroyView();
|
||||||
|
if(sTaskProxy != null) {
|
||||||
|
sTaskProxy.detachListener();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onClickStart(View v) {
|
||||||
|
sTaskProxy = new ModloaderListenerProxy();
|
||||||
|
FabricDownloadTask fabricDownloadTask = new FabricDownloadTask(sTaskProxy, mDestinationDir);
|
||||||
|
sTaskProxy.attachListener(this);
|
||||||
|
mStartButton.setEnabled(false);
|
||||||
|
new Thread(fabricDownloadTask).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onClickSelect(View v) {
|
||||||
|
VersionSelectorDialog.open(v.getContext(), true, (id, snapshot)->{
|
||||||
|
mSelectedGameVersion = id;
|
||||||
|
mSelectedVersionLabel.setText(mSelectedGameVersion);
|
||||||
|
mSelectedSnapshot = snapshot;
|
||||||
|
if(mSelectedLoaderVersion != null && sTaskProxy == null) mStartButton.setEnabled(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onClickRetry(View v) {
|
||||||
|
mLoaderVersionSpinner.setAdapter(null);
|
||||||
|
mStartButton.setEnabled(false);
|
||||||
|
mProgressBar.setVisibility(View.VISIBLE);
|
||||||
|
mRetryView.setVisibility(View.GONE);
|
||||||
|
new Thread(this).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
|
||||||
|
Adapter adapter = (Adapter) adapterView.getAdapter();
|
||||||
|
mSelectedLoaderVersion = (String) adapter.getItem(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNothingSelected(AdapterView<?> adapterView) {
|
||||||
|
mSelectedLoaderVersion = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDownloadFinished(File downloadedFile) {
|
||||||
|
Tools.runOnUiThread(()->{
|
||||||
|
Context context = requireContext();
|
||||||
|
sTaskProxy.detachListener();
|
||||||
|
sTaskProxy = null;
|
||||||
|
mStartButton.setEnabled(true);
|
||||||
|
Intent intent = new Intent(context, JavaGUILauncherActivity.class);
|
||||||
|
FabricUtils.addAutoInstallArgs(intent, downloadedFile, mSelectedGameVersion, mSelectedLoaderVersion, mSelectedSnapshot, true);
|
||||||
|
context.startActivity(intent);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDataNotAvailable() {
|
||||||
|
Tools.runOnUiThread(()->{
|
||||||
|
Context context = requireContext();
|
||||||
|
sTaskProxy.detachListener();
|
||||||
|
sTaskProxy = null;
|
||||||
|
mStartButton.setEnabled(true);
|
||||||
|
Tools.dialog(context,
|
||||||
|
context.getString(R.string.global_error),
|
||||||
|
context.getString(R.string.fabric_dl_cant_read_meta));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDownloadError(Exception e) {
|
||||||
|
Tools.runOnUiThread(()-> {
|
||||||
|
Context context = requireContext();
|
||||||
|
sTaskProxy.detachListener();
|
||||||
|
sTaskProxy = null;
|
||||||
|
mStartButton.setEnabled(true);
|
||||||
|
Tools.showError(context, e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
List<String> mLoaderVersions = FabricUtils.downloadLoaderVersionList(false);
|
||||||
|
if (mLoaderVersions != null) {
|
||||||
|
Tools.runOnUiThread(()->{
|
||||||
|
Context context = getContext();
|
||||||
|
if(context == null) return;
|
||||||
|
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(context, R.layout.support_simple_spinner_dropdown_item, mLoaderVersions);
|
||||||
|
mLoaderVersionSpinner.setAdapter(arrayAdapter);
|
||||||
|
mProgressBar.setVisibility(View.GONE);
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
Tools.runOnUiThread(()-> {
|
||||||
|
mRetryView.setVisibility(View.VISIBLE);
|
||||||
|
mProgressBar.setVisibility(View.GONE);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}catch (IOException e) {
|
||||||
|
Tools.runOnUiThread(()-> {
|
||||||
|
if(getContext() != null) Tools.showError(getContext(), e);
|
||||||
|
mRetryView.setVisibility(View.VISIBLE);
|
||||||
|
mProgressBar.setVisibility(View.GONE);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,146 @@
|
|||||||
|
package net.kdt.pojavlaunch.fragments;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.ExpandableListView;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
||||||
|
import net.kdt.pojavlaunch.JavaGUILauncherActivity;
|
||||||
|
import net.kdt.pojavlaunch.R;
|
||||||
|
import net.kdt.pojavlaunch.Tools;
|
||||||
|
import net.kdt.pojavlaunch.modloaders.ForgeDownloadTask;
|
||||||
|
import net.kdt.pojavlaunch.modloaders.ForgeUtils;
|
||||||
|
import net.kdt.pojavlaunch.modloaders.ForgeVersionListAdapter;
|
||||||
|
import net.kdt.pojavlaunch.modloaders.ModloaderDownloadListener;
|
||||||
|
import net.kdt.pojavlaunch.modloaders.ModloaderListenerProxy;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ForgeInstallFragment extends Fragment implements Runnable, View.OnClickListener, ExpandableListView.OnChildClickListener, ModloaderDownloadListener {
|
||||||
|
public static final String TAG = "ForgeInstallFragment";
|
||||||
|
private static ModloaderListenerProxy sTaskProxy;
|
||||||
|
private ExpandableListView mExpandableListView;
|
||||||
|
private ProgressBar mProgressBar;
|
||||||
|
private File mDestinationFile;
|
||||||
|
private LayoutInflater mInflater;
|
||||||
|
private View mRetryView;
|
||||||
|
|
||||||
|
public ForgeInstallFragment() {
|
||||||
|
super(R.layout.fragment_forge_installer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(@NonNull Context context) {
|
||||||
|
super.onAttach(context);
|
||||||
|
this.mInflater = LayoutInflater.from(context);
|
||||||
|
this.mDestinationFile = new File(context.getCacheDir(), "forge-installer.jar");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
mProgressBar = view.findViewById(R.id.forge_list_progress_bar);
|
||||||
|
mExpandableListView = view.findViewById(R.id.forge_expandable_version_list);
|
||||||
|
mExpandableListView.setOnChildClickListener(this);
|
||||||
|
mRetryView = view.findViewById(R.id.forge_installer_retry_layout);
|
||||||
|
view.findViewById(R.id.forge_installer_retry_button).setOnClickListener(this);
|
||||||
|
if(sTaskProxy != null) {
|
||||||
|
mExpandableListView.setEnabled(false);
|
||||||
|
sTaskProxy.attachListener(this);
|
||||||
|
}
|
||||||
|
new Thread(this).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroyView() {
|
||||||
|
if(sTaskProxy != null) sTaskProxy.detachListener();
|
||||||
|
super.onDestroyView();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
List<String> forgeVersions = ForgeUtils.downloadForgeVersions();
|
||||||
|
Tools.runOnUiThread(()->{
|
||||||
|
if(forgeVersions != null) {
|
||||||
|
mExpandableListView.setAdapter(new ForgeVersionListAdapter(forgeVersions, mInflater));
|
||||||
|
}else{
|
||||||
|
mRetryView.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
mProgressBar.setVisibility(View.GONE);
|
||||||
|
});
|
||||||
|
}catch (IOException e) {
|
||||||
|
Tools.runOnUiThread(()-> {
|
||||||
|
if (getContext() != null) {
|
||||||
|
Tools.showError(getContext(), e);
|
||||||
|
mRetryView.setVisibility(View.VISIBLE);
|
||||||
|
mProgressBar.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
mRetryView.setVisibility(View.GONE);
|
||||||
|
mProgressBar.setVisibility(View.VISIBLE);
|
||||||
|
new Thread(this).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onChildClick(ExpandableListView expandableListView, View view, int i, int i1, long l) {
|
||||||
|
String forgeVersion = (String)expandableListView.getExpandableListAdapter().getChild(i, i1);
|
||||||
|
sTaskProxy = new ModloaderListenerProxy();
|
||||||
|
ForgeDownloadTask downloadTask = new ForgeDownloadTask(sTaskProxy, forgeVersion, mDestinationFile);
|
||||||
|
sTaskProxy.attachListener(this);
|
||||||
|
mExpandableListView.setEnabled(false);
|
||||||
|
new Thread(downloadTask).start();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDownloadFinished(File downloadedFile) {
|
||||||
|
Tools.runOnUiThread(()->{
|
||||||
|
Context context = requireContext();
|
||||||
|
sTaskProxy.detachListener();
|
||||||
|
sTaskProxy = null;
|
||||||
|
mExpandableListView.setEnabled(true);
|
||||||
|
Intent modInstallerStartIntent = new Intent(context, JavaGUILauncherActivity.class);
|
||||||
|
ForgeUtils.addAutoInstallArgs(modInstallerStartIntent, downloadedFile, true);
|
||||||
|
context.startActivity(modInstallerStartIntent);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDataNotAvailable() {
|
||||||
|
Tools.runOnUiThread(()->{
|
||||||
|
Context context = requireContext();
|
||||||
|
sTaskProxy.detachListener();
|
||||||
|
sTaskProxy = null;
|
||||||
|
mExpandableListView.setEnabled(true);
|
||||||
|
Tools.dialog(context,
|
||||||
|
context.getString(R.string.global_error),
|
||||||
|
context.getString(R.string.forge_dl_no_installer));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDownloadError(Exception e) {
|
||||||
|
Tools.runOnUiThread(()->{
|
||||||
|
Context context = requireContext();
|
||||||
|
sTaskProxy.detachListener();
|
||||||
|
sTaskProxy = null;
|
||||||
|
mExpandableListView.setEnabled(true);
|
||||||
|
Tools.showError(context, e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -5,7 +5,6 @@ import static net.kdt.pojavlaunch.Tools.shareLog;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
@ -19,7 +18,6 @@ import net.kdt.pojavlaunch.R;
|
|||||||
import net.kdt.pojavlaunch.Tools;
|
import net.kdt.pojavlaunch.Tools;
|
||||||
import net.kdt.pojavlaunch.extra.ExtraConstants;
|
import net.kdt.pojavlaunch.extra.ExtraConstants;
|
||||||
import net.kdt.pojavlaunch.extra.ExtraCore;
|
import net.kdt.pojavlaunch.extra.ExtraCore;
|
||||||
import net.kdt.pojavlaunch.modloaders.ForgeDownloaderDialog;
|
|
||||||
import net.kdt.pojavlaunch.progresskeeper.ProgressKeeper;
|
import net.kdt.pojavlaunch.progresskeeper.ProgressKeeper;
|
||||||
|
|
||||||
public class MainMenuFragment extends Fragment {
|
public class MainMenuFragment extends Fragment {
|
||||||
@ -53,7 +51,7 @@ public class MainMenuFragment extends Fragment {
|
|||||||
mShareLogsButton.setOnClickListener((v) -> shareLog(requireContext()));
|
mShareLogsButton.setOnClickListener((v) -> shareLog(requireContext()));
|
||||||
|
|
||||||
mNewsButton.setOnLongClickListener((v)->{
|
mNewsButton.setOnLongClickListener((v)->{
|
||||||
new ForgeDownloaderDialog().show(view.getContext(), (ViewGroup) view);
|
Tools.swapFragment(requireActivity(), FabricInstallFragment.class, FabricInstallFragment.TAG, true, null);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package net.kdt.pojavlaunch.fragments;
|
package net.kdt.pojavlaunch.fragments;
|
||||||
|
|
||||||
import static net.kdt.pojavlaunch.extra.ExtraCore.getValue;
|
|
||||||
import static net.kdt.pojavlaunch.profiles.ProfileAdapter.CREATE_PROFILE_MAGIC;
|
import static net.kdt.pojavlaunch.profiles.ProfileAdapter.CREATE_PROFILE_MAGIC;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@ -11,17 +10,13 @@ import android.view.ViewGroup;
|
|||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.ExpandableListAdapter;
|
|
||||||
import android.widget.ExpandableListView;
|
|
||||||
import android.widget.Spinner;
|
import android.widget.Spinner;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
||||||
import net.kdt.pojavlaunch.JMinecraftVersionList;
|
|
||||||
import net.kdt.pojavlaunch.R;
|
import net.kdt.pojavlaunch.R;
|
||||||
import net.kdt.pojavlaunch.Tools;
|
import net.kdt.pojavlaunch.Tools;
|
||||||
import net.kdt.pojavlaunch.extra.ExtraConstants;
|
import net.kdt.pojavlaunch.extra.ExtraConstants;
|
||||||
@ -30,7 +25,7 @@ import net.kdt.pojavlaunch.multirt.MultiRTUtils;
|
|||||||
import net.kdt.pojavlaunch.multirt.RTSpinnerAdapter;
|
import net.kdt.pojavlaunch.multirt.RTSpinnerAdapter;
|
||||||
import net.kdt.pojavlaunch.multirt.Runtime;
|
import net.kdt.pojavlaunch.multirt.Runtime;
|
||||||
import net.kdt.pojavlaunch.prefs.LauncherPreferences;
|
import net.kdt.pojavlaunch.prefs.LauncherPreferences;
|
||||||
import net.kdt.pojavlaunch.profiles.VersionListAdapter;
|
import net.kdt.pojavlaunch.profiles.VersionSelectorDialog;
|
||||||
import net.kdt.pojavlaunch.value.launcherprofiles.LauncherProfiles;
|
import net.kdt.pojavlaunch.value.launcherprofiles.LauncherProfiles;
|
||||||
import net.kdt.pojavlaunch.value.launcherprofiles.MinecraftProfile;
|
import net.kdt.pojavlaunch.value.launcherprofiles.MinecraftProfile;
|
||||||
|
|
||||||
@ -117,28 +112,10 @@ public class ProfileEditorFragment extends Fragment {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Setup the expendable list behavior
|
// Setup the expendable list behavior
|
||||||
mVersionSelectButton.setOnClickListener(v -> {
|
mVersionSelectButton.setOnClickListener(v -> VersionSelectorDialog.open(v.getContext(), false, (id, snapshot)->{
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(mDefaultVersion.getContext());
|
mTempProfile.lastVersionId = id;
|
||||||
ExpandableListView expandableListView = (ExpandableListView) LayoutInflater.from(mDefaultVersion.getContext())
|
mDefaultVersion.setText(id);
|
||||||
.inflate(R.layout.dialog_expendable_list_view , null);
|
}));
|
||||||
JMinecraftVersionList jMinecraftVersionList = (JMinecraftVersionList) getValue(ExtraConstants.RELEASE_TABLE);
|
|
||||||
JMinecraftVersionList.Version[] versionArray;
|
|
||||||
if(jMinecraftVersionList == null || jMinecraftVersionList.versions == null) versionArray = new JMinecraftVersionList.Version[0];
|
|
||||||
else versionArray = jMinecraftVersionList.versions;
|
|
||||||
ExpandableListAdapter adapter = new VersionListAdapter(versionArray, mDefaultVersion.getContext());
|
|
||||||
|
|
||||||
expandableListView.setAdapter(adapter);
|
|
||||||
builder.setView(expandableListView);
|
|
||||||
AlertDialog dialog = builder.show();
|
|
||||||
|
|
||||||
expandableListView.setOnChildClickListener((parent, v1, groupPosition, childPosition, id) -> {
|
|
||||||
String version = ((String) adapter.getChild(groupPosition, childPosition));
|
|
||||||
mTempProfile.lastVersionId = version;
|
|
||||||
mDefaultVersion.setText(version);
|
|
||||||
dialog.dismiss();
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -0,0 +1,77 @@
|
|||||||
|
package net.kdt.pojavlaunch.modloaders;
|
||||||
|
|
||||||
|
import com.kdt.mcgui.ProgressLayout;
|
||||||
|
|
||||||
|
import net.kdt.pojavlaunch.R;
|
||||||
|
import net.kdt.pojavlaunch.Tools;
|
||||||
|
import net.kdt.pojavlaunch.progresskeeper.ProgressKeeper;
|
||||||
|
import net.kdt.pojavlaunch.utils.DownloadUtils;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public class FabricDownloadTask implements Runnable, Tools.DownloaderFeedback{
|
||||||
|
private final File mDestinationDir;
|
||||||
|
private final File mDestinationFile;
|
||||||
|
private final ModloaderDownloadListener mModloaderDownloadListener;
|
||||||
|
|
||||||
|
public FabricDownloadTask(ModloaderDownloadListener modloaderDownloadListener, File mDestinationDir) {
|
||||||
|
this.mModloaderDownloadListener = modloaderDownloadListener;
|
||||||
|
this.mDestinationDir = mDestinationDir;
|
||||||
|
this.mDestinationFile = new File(mDestinationDir, "fabric-installer.jar");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
ProgressKeeper.submitProgress(ProgressLayout.INSTALL_MODPACK, 0, R.string.fabric_dl_progress);
|
||||||
|
try {
|
||||||
|
if(runCatching()) mModloaderDownloadListener.onDownloadFinished(mDestinationFile);
|
||||||
|
}catch (IOException e) {
|
||||||
|
mModloaderDownloadListener.onDownloadError(e);
|
||||||
|
}
|
||||||
|
ProgressKeeper.submitProgress(ProgressLayout.INSTALL_MODPACK, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean runCatching() throws IOException {
|
||||||
|
if(!mDestinationDir.exists() && !mDestinationDir.mkdirs()) throw new IOException("Failed to create cache directory");
|
||||||
|
String[] urlAndVersion = FabricUtils.getInstallerUrlAndVersion();
|
||||||
|
if(urlAndVersion == null) {
|
||||||
|
mModloaderDownloadListener.onDataNotAvailable();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
File versionFile = new File(mDestinationDir, "fabric-installer-version");
|
||||||
|
boolean shouldDownloadInstaller = true;
|
||||||
|
if(urlAndVersion[1] != null && versionFile.canRead()) { // if we know the latest version that we have and the server has
|
||||||
|
try {
|
||||||
|
shouldDownloadInstaller = !urlAndVersion[1].equals(Tools.read(versionFile.getAbsolutePath()));
|
||||||
|
}catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(shouldDownloadInstaller) {
|
||||||
|
if (urlAndVersion[0] != null) {
|
||||||
|
byte[] buffer = new byte[8192];
|
||||||
|
DownloadUtils.downloadFileMonitored(urlAndVersion[0], mDestinationFile, buffer, this);
|
||||||
|
if(urlAndVersion[1] != null) {
|
||||||
|
try {
|
||||||
|
Tools.write(versionFile.getAbsolutePath(), urlAndVersion[1]);
|
||||||
|
}catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
mModloaderDownloadListener.onDataNotAvailable();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateProgress(int curr, int max) {
|
||||||
|
int progress100 = (int)(((float)curr / (float)max)*100f);
|
||||||
|
ProgressKeeper.submitProgress(ProgressLayout.INSTALL_MODPACK, progress100, R.string.fabric_dl_progress);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
package net.kdt.pojavlaunch.modloaders;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
public interface FabricMetaReader {
|
||||||
|
boolean processMetadata(JSONObject jsonObject) throws JSONException;
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
package net.kdt.pojavlaunch.modloaders;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
|
||||||
|
import net.kdt.pojavlaunch.Tools;
|
||||||
|
import net.kdt.pojavlaunch.utils.DownloadUtils;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class FabricUtils {
|
||||||
|
private static final String FABRIC_INSTALLER_METADATA_URL = "https://meta.fabricmc.net/v2/versions/installer";
|
||||||
|
private static final String FABRIC_LOADER_METADATA_URL = "https://meta.fabricmc.net/v2/versions/loader";
|
||||||
|
public static List<String> downloadLoaderVersionList(boolean onlyStable) throws IOException {
|
||||||
|
String loaderMetadata = DownloadUtils.downloadString(FABRIC_LOADER_METADATA_URL);
|
||||||
|
List<String> loaderList = new ArrayList<>();
|
||||||
|
if(enumerateMetadata(loaderMetadata, (object)->{
|
||||||
|
if(onlyStable && !object.getBoolean("stable")) return false;
|
||||||
|
loaderList.add(object.getString("version"));
|
||||||
|
return false;
|
||||||
|
}) == null) return null;
|
||||||
|
return loaderList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String[] getInstallerUrlAndVersion() throws IOException{
|
||||||
|
String installerMetadata = DownloadUtils.downloadString(FABRIC_INSTALLER_METADATA_URL);
|
||||||
|
JSONObject selectedMetadata = enumerateMetadata(installerMetadata, (object)-> object.getBoolean("stable"));
|
||||||
|
if(selectedMetadata == null) return null;
|
||||||
|
return new String[] {selectedMetadata.optString("url"), selectedMetadata.optString("version")};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void addAutoInstallArgs(Intent intent, File modInstalllerJar,
|
||||||
|
String gameVersion, String loaderVersion,
|
||||||
|
boolean isSnapshot, boolean createProfile) {
|
||||||
|
intent.putExtra("javaArgs", "-jar " + modInstalllerJar.getAbsolutePath() + " client -dir "+ Tools.DIR_GAME_NEW
|
||||||
|
+ " -mcversion "+gameVersion +" -loader "+loaderVersion +
|
||||||
|
(isSnapshot ? " -snapshot" : "") +
|
||||||
|
(createProfile ? "" : " -noprofile"));
|
||||||
|
intent.putExtra("openLogOutput", true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static JSONObject enumerateMetadata(String inputMetadata, FabricMetaReader metaReader) {
|
||||||
|
try {
|
||||||
|
JSONArray fullMetadata = new JSONArray(inputMetadata);
|
||||||
|
JSONObject metadataObject = null;
|
||||||
|
for(int i = 0; i < fullMetadata.length(); i++) {
|
||||||
|
metadataObject = fullMetadata.getJSONObject(i);
|
||||||
|
if(metaReader.processMetadata(metadataObject)) return metadataObject;
|
||||||
|
}
|
||||||
|
return metadataObject;
|
||||||
|
}catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +0,0 @@
|
|||||||
package net.kdt.pojavlaunch.modloaders;
|
|
||||||
|
|
||||||
public interface ForgeDownloadListener {
|
|
||||||
void onDownloadFinished();
|
|
||||||
void onInstallerNotAvailable();
|
|
||||||
void onDownloadError(Exception e);
|
|
||||||
}
|
|
@ -14,9 +14,9 @@ import java.io.IOException;
|
|||||||
public class ForgeDownloadTask implements Runnable, Tools.DownloaderFeedback {
|
public class ForgeDownloadTask implements Runnable, Tools.DownloaderFeedback {
|
||||||
private final String mForgeUrl;
|
private final String mForgeUrl;
|
||||||
private final String mForgeVersion;
|
private final String mForgeVersion;
|
||||||
private final File mDestinationFile;
|
public final File mDestinationFile;
|
||||||
private final ForgeDownloadListener mListener;
|
private final ModloaderDownloadListener mListener;
|
||||||
public ForgeDownloadTask(ForgeDownloadListener listener, String forgeVersion, File destinationFile) {
|
public ForgeDownloadTask(ModloaderDownloadListener listener, String forgeVersion, File destinationFile) {
|
||||||
this.mListener = listener;
|
this.mListener = listener;
|
||||||
this.mForgeUrl = ForgeUtils.getInstallerUrl(forgeVersion);
|
this.mForgeUrl = ForgeUtils.getInstallerUrl(forgeVersion);
|
||||||
this.mForgeVersion = forgeVersion;
|
this.mForgeVersion = forgeVersion;
|
||||||
@ -28,10 +28,10 @@ public class ForgeDownloadTask implements Runnable, Tools.DownloaderFeedback {
|
|||||||
try {
|
try {
|
||||||
byte[] buffer = new byte[8192];
|
byte[] buffer = new byte[8192];
|
||||||
DownloadUtils.downloadFileMonitored(mForgeUrl, mDestinationFile, buffer, this);
|
DownloadUtils.downloadFileMonitored(mForgeUrl, mDestinationFile, buffer, this);
|
||||||
mListener.onDownloadFinished();
|
mListener.onDownloadFinished(mDestinationFile);
|
||||||
}catch (IOException e) {
|
}catch (IOException e) {
|
||||||
if(e instanceof FileNotFoundException) {
|
if(e instanceof FileNotFoundException) {
|
||||||
mListener.onInstallerNotAvailable();
|
mListener.onDataNotAvailable();
|
||||||
}else{
|
}else{
|
||||||
mListener.onDownloadError(e);
|
mListener.onDownloadError(e);
|
||||||
}
|
}
|
||||||
|
@ -1,94 +0,0 @@
|
|||||||
package net.kdt.pojavlaunch.modloaders;
|
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Looper;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.ExpandableListView;
|
|
||||||
import android.widget.ProgressBar;
|
|
||||||
|
|
||||||
import net.kdt.pojavlaunch.JavaGUILauncherActivity;
|
|
||||||
import net.kdt.pojavlaunch.R;
|
|
||||||
import net.kdt.pojavlaunch.Tools;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class ForgeDownloaderDialog implements Runnable, ExpandableListView.OnChildClickListener, ForgeDownloadListener {
|
|
||||||
private final Handler mHandler = new Handler(Looper.getMainLooper());
|
|
||||||
private ExpandableListView mExpandableListView;
|
|
||||||
private ProgressBar mProgressBar;
|
|
||||||
private AlertDialog mAlertDialog;
|
|
||||||
private File mDestinationFile;
|
|
||||||
private Context mContext;
|
|
||||||
public void show(Context context, ViewGroup root) {
|
|
||||||
this.mContext = context;
|
|
||||||
this.mDestinationFile = new File(context.getCacheDir(), "forge-installer.jar");
|
|
||||||
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context);
|
|
||||||
View dialogView = LayoutInflater.from(context).inflate(R.layout.dialog_expandable_forge_list, root, false);
|
|
||||||
mProgressBar = dialogView.findViewById(R.id.forge_list_progress_bar);
|
|
||||||
mExpandableListView = dialogView.findViewById(R.id.forge_expandable_version_list);
|
|
||||||
mExpandableListView.setOnChildClickListener(this);
|
|
||||||
dialogBuilder.setView(dialogView);
|
|
||||||
mAlertDialog = dialogBuilder.show();
|
|
||||||
new Thread(this).start();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
List<String> forgeVersions = ForgeUtils.downloadForgeVersions();
|
|
||||||
mHandler.post(()->{
|
|
||||||
if(forgeVersions != null) {
|
|
||||||
mProgressBar.setVisibility(View.GONE);
|
|
||||||
mExpandableListView.setAdapter(new ForgeVersionListAdapter(forgeVersions, LayoutInflater.from(mContext)));
|
|
||||||
}else{
|
|
||||||
mAlertDialog.dismiss();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}catch (IOException e) {
|
|
||||||
mHandler.post(()->{
|
|
||||||
mAlertDialog.dismiss();
|
|
||||||
Tools.showError(mContext, e);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onChildClick(ExpandableListView expandableListView, View view, int i, int i1, long l) {
|
|
||||||
String forgeVersion = (String)expandableListView.getExpandableListAdapter().getChild(i, i1);
|
|
||||||
new Thread(new ForgeDownloadTask(this, forgeVersion, mDestinationFile)).start();
|
|
||||||
mAlertDialog.dismiss();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDownloadFinished() {
|
|
||||||
Intent intent = new Intent(mContext, JavaGUILauncherActivity.class);
|
|
||||||
ForgeUtils.addAutoInstallArgs(intent, mDestinationFile, true); // since it's a user-invoked install, we want to create a new profile
|
|
||||||
mContext.startActivity(intent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onInstallerNotAvailable() {
|
|
||||||
mHandler.post(()-> {
|
|
||||||
mAlertDialog.dismiss();
|
|
||||||
Tools.dialog(mContext,
|
|
||||||
mContext.getString(R.string.global_error),
|
|
||||||
mContext.getString(R.string.forge_dl_no_installer));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDownloadError(Exception e) {
|
|
||||||
mHandler.post(mAlertDialog::dismiss);
|
|
||||||
Tools.showError(mContext, e);
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,9 @@
|
|||||||
|
package net.kdt.pojavlaunch.modloaders;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
public interface ModloaderDownloadListener {
|
||||||
|
void onDownloadFinished(File downloadedFile);
|
||||||
|
void onDataNotAvailable();
|
||||||
|
void onDownloadError(Exception e);
|
||||||
|
}
|
@ -0,0 +1,61 @@
|
|||||||
|
package net.kdt.pojavlaunch.modloaders;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
public class ModloaderListenerProxy implements ModloaderDownloadListener {
|
||||||
|
public static final int PROXY_RESULT_NONE = -1;
|
||||||
|
public static final int PROXY_RESULT_FINISHED = 0;
|
||||||
|
public static final int PROXY_RESULT_NOT_AVAILABLE = 1;
|
||||||
|
public static final int PROXY_RESULT_ERROR = 2;
|
||||||
|
private ModloaderDownloadListener mDestinationListener;
|
||||||
|
private Object mProxyResultObject;
|
||||||
|
private int mProxyResult = PROXY_RESULT_NONE;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void onDownloadFinished(File downloadedFile) {
|
||||||
|
if(mDestinationListener != null) {
|
||||||
|
mDestinationListener.onDownloadFinished(downloadedFile);
|
||||||
|
}else{
|
||||||
|
mProxyResult = PROXY_RESULT_FINISHED;
|
||||||
|
mProxyResultObject = downloadedFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void onDataNotAvailable() {
|
||||||
|
if(mDestinationListener != null) {
|
||||||
|
mDestinationListener.onDataNotAvailable();
|
||||||
|
}else{
|
||||||
|
mProxyResult = PROXY_RESULT_NOT_AVAILABLE;
|
||||||
|
mProxyResultObject = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized void onDownloadError(Exception e) {
|
||||||
|
if(mDestinationListener != null) {
|
||||||
|
mDestinationListener.onDownloadError(e);
|
||||||
|
}else {
|
||||||
|
mProxyResult = PROXY_RESULT_ERROR;
|
||||||
|
mProxyResultObject = e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void attachListener(ModloaderDownloadListener listener) {
|
||||||
|
switch(mProxyResult) {
|
||||||
|
case PROXY_RESULT_FINISHED:
|
||||||
|
listener.onDownloadFinished((File) mProxyResultObject);
|
||||||
|
break;
|
||||||
|
case PROXY_RESULT_NOT_AVAILABLE:
|
||||||
|
listener.onDataNotAvailable();
|
||||||
|
break;
|
||||||
|
case PROXY_RESULT_ERROR:
|
||||||
|
listener.onDownloadError((Exception) mProxyResultObject);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mDestinationListener = listener;
|
||||||
|
}
|
||||||
|
public synchronized void detachListener() {
|
||||||
|
mDestinationListener = null;
|
||||||
|
}
|
||||||
|
}
|
@ -24,8 +24,11 @@ public class VersionListAdapter extends BaseExpandableListAdapter implements Exp
|
|||||||
private final String[] mGroups;
|
private final String[] mGroups;
|
||||||
private final String[] mInstalledVersions;
|
private final String[] mInstalledVersions;
|
||||||
private final List<?>[] mData;
|
private final List<?>[] mData;
|
||||||
|
private final boolean mHideCustomVersions;
|
||||||
|
private final int mSnapshotListPosition;
|
||||||
|
|
||||||
public VersionListAdapter(JMinecraftVersionList.Version[] versionList, Context ctx){
|
public VersionListAdapter(JMinecraftVersionList.Version[] versionList, boolean hideCustomVersions, Context ctx){
|
||||||
|
mHideCustomVersions = hideCustomVersions;
|
||||||
mLayoutInflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
mLayoutInflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||||
|
|
||||||
List<JMinecraftVersionList.Version> releaseList = new FilteredSubList<>(versionList, item -> item.type.equals("release"));
|
List<JMinecraftVersionList.Version> releaseList = new FilteredSubList<>(versionList, item -> item.type.equals("release"));
|
||||||
@ -43,6 +46,7 @@ public class VersionListAdapter extends BaseExpandableListAdapter implements Exp
|
|||||||
ctx.getString(R.string.mcl_setting_veroption_oldalpha)
|
ctx.getString(R.string.mcl_setting_veroption_oldalpha)
|
||||||
};
|
};
|
||||||
mData = new List[]{ releaseList, snapshotList, betaList, alphaList};
|
mData = new List[]{ releaseList, snapshotList, betaList, alphaList};
|
||||||
|
mSnapshotListPosition = 1;
|
||||||
}else{
|
}else{
|
||||||
mGroups = new String[]{
|
mGroups = new String[]{
|
||||||
ctx.getString(R.string.mcl_setting_veroption_installed),
|
ctx.getString(R.string.mcl_setting_veroption_installed),
|
||||||
@ -52,6 +56,7 @@ public class VersionListAdapter extends BaseExpandableListAdapter implements Exp
|
|||||||
ctx.getString(R.string.mcl_setting_veroption_oldalpha)
|
ctx.getString(R.string.mcl_setting_veroption_oldalpha)
|
||||||
};
|
};
|
||||||
mData = new List[]{Arrays.asList(mInstalledVersions), releaseList, snapshotList, betaList, alphaList};
|
mData = new List[]{Arrays.asList(mInstalledVersions), releaseList, snapshotList, betaList, alphaList};
|
||||||
|
mSnapshotListPosition = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,7 +121,12 @@ public class VersionListAdapter extends BaseExpandableListAdapter implements Exp
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isSnapshotSelected(int groupPosition) {
|
||||||
|
return groupPosition == mSnapshotListPosition;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean areInstalledVersionsAvailable(){
|
private boolean areInstalledVersionsAvailable(){
|
||||||
|
if(mHideCustomVersions) return false;
|
||||||
return !(mInstalledVersions == null || mInstalledVersions.length == 0);
|
return !(mInstalledVersions == null || mInstalledVersions.length == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
package net.kdt.pojavlaunch.profiles;
|
||||||
|
|
||||||
|
import static net.kdt.pojavlaunch.extra.ExtraCore.getValue;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.widget.ExpandableListView;
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
|
||||||
|
import net.kdt.pojavlaunch.JMinecraftVersionList;
|
||||||
|
import net.kdt.pojavlaunch.R;
|
||||||
|
import net.kdt.pojavlaunch.extra.ExtraConstants;
|
||||||
|
|
||||||
|
public class VersionSelectorDialog {
|
||||||
|
public static void open(Context context, boolean hideCustomVersions, VersionSelectorListener listener) {
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||||
|
ExpandableListView expandableListView = (ExpandableListView) LayoutInflater.from(context)
|
||||||
|
.inflate(R.layout.dialog_expendable_list_view , null);
|
||||||
|
JMinecraftVersionList jMinecraftVersionList = (JMinecraftVersionList) getValue(ExtraConstants.RELEASE_TABLE);
|
||||||
|
JMinecraftVersionList.Version[] versionArray;
|
||||||
|
if(jMinecraftVersionList == null || jMinecraftVersionList.versions == null) versionArray = new JMinecraftVersionList.Version[0];
|
||||||
|
else versionArray = jMinecraftVersionList.versions;
|
||||||
|
VersionListAdapter adapter = new VersionListAdapter(versionArray, hideCustomVersions, context);
|
||||||
|
|
||||||
|
expandableListView.setAdapter(adapter);
|
||||||
|
builder.setView(expandableListView);
|
||||||
|
AlertDialog dialog = builder.show();
|
||||||
|
|
||||||
|
expandableListView.setOnChildClickListener((parent, v1, groupPosition, childPosition, id) -> {
|
||||||
|
String version = adapter.getChild(groupPosition, childPosition);
|
||||||
|
listener.onVersionSelected(version, adapter.isSnapshotSelected(groupPosition));
|
||||||
|
dialog.dismiss();
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
package net.kdt.pojavlaunch.profiles;
|
||||||
|
|
||||||
|
public interface VersionSelectorListener {
|
||||||
|
void onVersionSelected(String versionId, boolean isSnapshot);
|
||||||
|
}
|
@ -6,9 +6,7 @@ import android.app.Service;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.Looper;
|
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
@ -28,7 +26,6 @@ import net.kdt.pojavlaunch.progresskeeper.TaskCountListener;
|
|||||||
*/
|
*/
|
||||||
public class ProgressService extends Service implements TaskCountListener {
|
public class ProgressService extends Service implements TaskCountListener {
|
||||||
|
|
||||||
private final Handler mainThreadHandler = new Handler(Looper.getMainLooper());
|
|
||||||
private NotificationManagerCompat notificationManagerCompat;
|
private NotificationManagerCompat notificationManagerCompat;
|
||||||
|
|
||||||
/** Simple wrapper to start the service */
|
/** Simple wrapper to start the service */
|
||||||
@ -85,7 +82,7 @@ public class ProgressService extends Service implements TaskCountListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onUpdateTaskCount(int taskCount) {
|
public void onUpdateTaskCount(int taskCount) {
|
||||||
mainThreadHandler.post(()->{
|
Tools.MAIN_HANDLER.post(()->{
|
||||||
if(taskCount > 0) {
|
if(taskCount > 0) {
|
||||||
mNotificationBuilder.setContentText(getString(R.string.progresslayout_tasks_in_progress, taskCount));
|
mNotificationBuilder.setContentText(getString(R.string.progresslayout_tasks_in_progress, taskCount));
|
||||||
notificationManagerCompat.notify(1, mNotificationBuilder.build());
|
notificationManagerCompat.notify(1, mNotificationBuilder.build());
|
||||||
|
@ -183,6 +183,8 @@ public class AsyncMinecraftDownloader {
|
|||||||
os.close();
|
os.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (DownloaderException e) {
|
||||||
|
throw e;
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Log.e("AsyncMcDownloader", e.toString(),e );
|
Log.e("AsyncMcDownloader", e.toString(),e );
|
||||||
ProgressKeeper.submitProgress(ProgressLayout.DOWNLOAD_MINECRAFT, -1, -1);
|
ProgressKeeper.submitProgress(ProgressLayout.DOWNLOAD_MINECRAFT, -1, -1);
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:orientation="vertical">
|
|
||||||
<ExpandableListView
|
|
||||||
android:id="@+id/forge_expandable_version_list"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_weight="1">
|
|
||||||
</ExpandableListView>
|
|
||||||
|
|
||||||
<ProgressBar
|
|
||||||
android:id="@+id/forge_list_progress_bar"
|
|
||||||
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:indeterminate="true" />
|
|
||||||
</LinearLayout>
|
|
@ -0,0 +1,135 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/background_app">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/fabric_installer_label_loader_ver"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:text="@string/fabric_dl_loader_version"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<Spinner
|
||||||
|
android:id="@+id/fabric_installer_loader_ver_spinner"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:minHeight="48dp"
|
||||||
|
android:background="@drawable/background_line"
|
||||||
|
android:paddingVertical="0dp"
|
||||||
|
android:paddingStart="7dp"
|
||||||
|
android:paddingEnd="7dp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/fabric_installer_label_loader_ver" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="@dimen/_8sdp"
|
||||||
|
android:paddingHorizontal="@dimen/_8sdp"
|
||||||
|
android:rotation="180"
|
||||||
|
android:src="@drawable/spinner_arrow"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/fabric_installer_loader_ver_spinner"
|
||||||
|
app:layout_constraintEnd_toEndOf="@+id/fabric_installer_loader_ver_spinner"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/fabric_installer_loader_ver_spinner" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/fabric_installer_retry_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingTop="@dimen/fragment_padding_medium"
|
||||||
|
android:paddingBottom="@dimen/fragment_padding_medium"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/fabric_installer_loader_ver_spinner">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginStart="10dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:text="@string/forge_dl_failed_to_load_list"
|
||||||
|
android:textColor="#FFFF0000"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/fabric_installer_retry_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/global_retry" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/fabric_installer_game_version"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:text="@string/fabric_dl_game_version"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/fabric_installer_retry_layout" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/fabric_installer_version_select_label"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="@drawable/background_line"
|
||||||
|
android:hint="@string/version_select_hint"
|
||||||
|
android:paddingHorizontal="@dimen/_12sdp"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/fabric_installer_game_version_change"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/fabric_installer_game_version" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/fabric_installer_game_version_change"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:text="@string/global_select"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/fabric_installer_version_select_label"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/fabric_installer_version_select_label" />
|
||||||
|
|
||||||
|
<com.kdt.mcgui.MineButton
|
||||||
|
android:id="@+id/fabric_installer_start_button"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:enabled="false"
|
||||||
|
android:text="@string/fabric_dl_install"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/fabric_installer_progress_bar"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/fabric_installer_version_select_label"
|
||||||
|
app:layout_constraintVertical_bias="1.0" />
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/fabric_installer_progress_bar"
|
||||||
|
style="?android:attr/progressBarStyleHorizontal"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:indeterminate="true"
|
||||||
|
android:visibility="visible"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -0,0 +1,58 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:background="@color/background_app">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/forge_dl_select_version"
|
||||||
|
android:paddingTop="@dimen/fragment_padding_medium"
|
||||||
|
android:paddingBottom="@dimen/fragment_padding_medium"
|
||||||
|
android:textColor="@color/primary_text" />
|
||||||
|
|
||||||
|
<ExpandableListView
|
||||||
|
android:scrollbarThumbVertical="@color/minebutton_color"
|
||||||
|
android:id="@+id/forge_expandable_version_list"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1">
|
||||||
|
|
||||||
|
</ExpandableListView>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/forge_installer_retry_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingTop="@dimen/fragment_padding_medium"
|
||||||
|
android:paddingBottom="@dimen/fragment_padding_medium"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginStart="10dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:text="@string/forge_dl_failed_to_load_list"
|
||||||
|
android:textColor="#FFFF0000"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/forge_installer_retry_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/global_retry" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<ProgressBar
|
||||||
|
android:id="@+id/forge_list_progress_bar"
|
||||||
|
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:indeterminate="true" />
|
||||||
|
</LinearLayout>
|
@ -53,7 +53,7 @@
|
|||||||
android:layout_marginTop="32dp"
|
android:layout_marginTop="32dp"
|
||||||
android:layout_marginEnd="@dimen/_4sdp"
|
android:layout_marginEnd="@dimen/_4sdp"
|
||||||
android:background="@drawable/background_line"
|
android:background="@drawable/background_line"
|
||||||
android:hint="Select a version"
|
android:hint="@string/version_select_hint"
|
||||||
android:paddingHorizontal="@dimen/_12sdp"
|
android:paddingHorizontal="@dimen/_12sdp"
|
||||||
android:textSize="@dimen/_13ssp"
|
android:textSize="@dimen/_13ssp"
|
||||||
|
|
||||||
|
@ -128,6 +128,7 @@
|
|||||||
<string name="global_error_field_empty">This field can\'t be empty</string>
|
<string name="global_error_field_empty">This field can\'t be empty</string>
|
||||||
<string name="global_waiting">Wait</string>
|
<string name="global_waiting">Wait</string>
|
||||||
<string name="global_select">Select</string>
|
<string name="global_select">Select</string>
|
||||||
|
<string name="global_retry">Retry</string>
|
||||||
|
|
||||||
<!-- MainActivity: strings -->
|
<!-- MainActivity: strings -->
|
||||||
<string name="mcn_exit_title">Application/Game exited with code %d, check latestlog.txt for more details.</string>
|
<string name="mcn_exit_title">Application/Game exited with code %d, check latestlog.txt for more details.</string>
|
||||||
@ -372,7 +373,14 @@
|
|||||||
<string name="preference_deadzone_scale_description">Increase it if the joystick drifts</string>
|
<string name="preference_deadzone_scale_description">Increase it if the joystick drifts</string>
|
||||||
<string name="preference_force_big_core_title">Force renderer to run on the big core</string>
|
<string name="preference_force_big_core_title">Force renderer to run on the big core</string>
|
||||||
<string name="preference_force_big_core_desc">Forces the Minecraft render thread to run on the core with the highest max frequency</string>
|
<string name="preference_force_big_core_desc">Forces the Minecraft render thread to run on the core with the highest max frequency</string>
|
||||||
|
<string name="version_select_hint">Select a version</string>
|
||||||
<string name="forge_dl_progress">Downloading installer for %s</string>
|
<string name="forge_dl_progress">Downloading installer for %s</string>
|
||||||
<string name="forge_dl_failed_to_load_list">Failed to load the version list</string>
|
<string name="forge_dl_failed_to_load_list">Failed to load the version list!</string>
|
||||||
<string name="forge_dl_no_installer">Sorry, but this version of Forge does not have an installer, which is not yet supported.</string>
|
<string name="forge_dl_no_installer">Sorry, but this version of Forge does not have an installer, which is not yet supported.</string>
|
||||||
|
<string name="forge_dl_select_version">Select Forge version</string>
|
||||||
|
<string name="fabric_dl_progress">Downloading Fabric installer</string>
|
||||||
|
<string name="fabric_dl_loader_version">Fabric loader version</string>
|
||||||
|
<string name="fabric_dl_game_version">Minecraft version</string>
|
||||||
|
<string name="fabric_dl_install">Install</string>
|
||||||
|
<string name="fabric_dl_cant_read_meta">Failed to read Fabric metadata. Please try again later.</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user