update ui

This commit is contained in:
Tungstend 2022-12-10 18:43:40 +08:00
parent 7c9ca6fbae
commit 2d53d38401
5 changed files with 260 additions and 2 deletions

View File

@ -123,6 +123,22 @@ public abstract class PageManager {
}
}
public void dismissAllTempPagesCreatedByPage(int id) {
FCLCommonPage commonPage = getPageById(id);
commonPage.getCurrentTempPage().dismiss();
commonPage.getAllTempPages().clear();
commonPage.setCurrentTempPage(null);
if (currentPage == commonPage) {
commonPage.onStart();
}
}
public void dismissAllTempPages() {
for (FCLCommonPage page : allPages) {
dismissAllTempPagesCreatedByPage(page.getId());
}
}
public void onPause() {
for (FCLCommonPage page : allPages) {
page.onPause();

View File

@ -1,15 +1,64 @@
package com.tungsten.fcl.ui.manage;
import android.content.Context;
import static com.tungsten.fcl.ui.download.InstallersPage.alertFailureMessage;
import android.app.Activity;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ScrollView;
import androidx.appcompat.app.AppCompatDialog;
import androidx.appcompat.widget.LinearLayoutCompat;
import com.tungsten.fcl.R;
import com.tungsten.fcl.setting.DownloadProviders;
import com.tungsten.fcl.setting.Profile;
import com.tungsten.fcl.ui.InstallerItem;
import com.tungsten.fcl.ui.PageManager;
import com.tungsten.fcl.ui.TaskDialog;
import com.tungsten.fcl.ui.download.InstallerVersionPage;
import com.tungsten.fcl.util.AndroidUtils;
import com.tungsten.fcl.util.RequestCodes;
import com.tungsten.fcl.util.TaskCancellationAction;
import com.tungsten.fclcore.download.LibraryAnalyzer;
import com.tungsten.fclcore.download.RemoteVersion;
import com.tungsten.fclcore.game.Version;
import com.tungsten.fclcore.task.Schedulers;
import com.tungsten.fclcore.task.Task;
import com.tungsten.fclcore.task.TaskExecutor;
import com.tungsten.fclcore.task.TaskListener;
import com.tungsten.fcllibrary.browser.FileBrowser;
import com.tungsten.fcllibrary.browser.options.LibMode;
import com.tungsten.fcllibrary.browser.options.SelectionMode;
import com.tungsten.fcllibrary.component.dialog.FCLAlertDialog;
import com.tungsten.fcllibrary.component.ui.FCLCommonPage;
import com.tungsten.fcllibrary.component.view.FCLUILayout;
import com.tungsten.fcllibrary.util.ConvertUtils;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
public class InstallerListPage extends FCLCommonPage implements ManageUI.VersionLoadable {
private Profile profile;
private String versionId;
private Version version;
private String gameVersion;
private ScrollView scrollView;
private LinearLayoutCompat parent;
public InstallerListPage(Context context, int id, FCLUILayout parent, int resId) {
super(context, id, parent, resId);
create();
}
private void create() {
scrollView = findViewById(R.id.scroll);
}
@Override
@ -18,7 +67,179 @@ public class InstallerListPage extends FCLCommonPage implements ManageUI.Version
}
@Override
public void loadVersion(Profile profile, String version) {
public void loadVersion(Profile profile, String versionId) {
this.profile = profile;
this.versionId = versionId;
this.version = profile.getRepository().getVersion(versionId);
this.gameVersion = null;
CompletableFuture.supplyAsync(() -> {
gameVersion = profile.getRepository().getGameVersion(version).orElse(null);
return LibraryAnalyzer.analyze(profile.getRepository().getResolvedPreservingPatchesVersion(versionId));
}).thenAcceptAsync(analyzer -> {
Function<String, Runnable> removeAction = libraryId -> () -> profile.getDependency().removeLibraryAsync(version, libraryId)
.thenComposeAsync(profile.getRepository()::saveAsync)
.withComposeAsync(profile.getRepository().refreshVersionsAsync())
.withRunAsync(Schedulers.androidUIThread(), () -> loadVersion(this.profile, this.versionId))
.start();
clear();
InstallerItem.InstallerItemGroup group = new InstallerItem.InstallerItemGroup(getContext());
// Conventional libraries: game, fabric, quilt, forge, liteloader, optifine
for (InstallerItem installerItem : group.getLibraries()) {
String libraryId = installerItem.getLibraryId();
String libraryVersion = analyzer.getVersion(libraryId).orElse(null);
installerItem.libraryVersion.set(libraryVersion);
installerItem.upgradable.set(libraryVersion != null);
installerItem.installable.set(true);
installerItem.action.set(() -> {
InstallerVersionPage page = new InstallerVersionPage(getContext(), PageManager.PAGE_ID_TEMP, getParent(), R.layout.page_install_version, gameVersion, libraryId, remoteVersion -> {
if (libraryVersion == null) {
finish(profile, remoteVersion);
} else {
FCLAlertDialog.Builder builder = new FCLAlertDialog.Builder(getContext());
builder.setCancelable(false);
builder.setAlertLevel(FCLAlertDialog.AlertLevel.INFO);
builder.setTitle(getContext().getString(R.string.install_change_version));
builder.setMessage(AndroidUtils.getLocalizedText(getContext(), "install_change_version_confirm", AndroidUtils.getLocalizedText(getContext(), "install_installer_" + libraryId), libraryVersion, remoteVersion.getSelfVersion()));
builder.setPositiveButton(() -> finish(profile, remoteVersion));
builder.setNegativeButton(null);
}
});
ManagePageManager.getInstance().showTempPage(page);
});
boolean removable = !"game".equals(libraryId) && libraryVersion != null;
installerItem.removable.set(removable);
if (removable) {
Runnable action = removeAction.apply(libraryId);
installerItem.removeAction.set(action);
}
addView(installerItem);
}
}, Schedulers.androidUIThread());
}
public void installOffline() {
ArrayList<String> suffix = new ArrayList<>();
suffix.add(".jar");
FileBrowser.Builder builder = new FileBrowser.Builder(getContext());
builder.setTitle(getContext().getString(R.string.install_installer_install_offline_extension));
builder.setLibMode(LibMode.FILE_CHOOSER);
builder.setSelectionMode(SelectionMode.SINGLE_SELECTION);
builder.setSuffix(suffix);
builder.create().browse(getActivity(), RequestCodes.SELECT_AUTO_INSTALLER_CODE, (requestCode, resultCode, data) -> {
if (requestCode == RequestCodes.SELECT_AUTO_INSTALLER_CODE && resultCode == Activity.RESULT_OK && data != null) {
String path = FileBrowser.getSelectedFiles(data).get(0);
if (new File(path).exists()) {
doInstallOffline(new File(path));
}
}
});
}
private void doInstallOffline(File file) {
Task<?> task = profile.getDependency().installLibraryAsync(version, file.toPath())
.thenComposeAsync(profile.getRepository()::saveAsync)
.thenComposeAsync(profile.getRepository().refreshVersionsAsync());
task.setName(getContext().getString(R.string.install_installer_install_offline));
TaskExecutor executor = task.executor(new TaskListener() {
@Override
public void onStop(boolean success, TaskExecutor executor) {
Schedulers.androidUIThread().execute(() -> {
if (success) {
loadVersion(profile, versionId);
FCLAlertDialog.Builder builder = new FCLAlertDialog.Builder(getContext());
builder.setAlertLevel(FCLAlertDialog.AlertLevel.INFO);
builder.setCancelable(false);
builder.setMessage(getContext().getString(R.string.install_success));
builder.setNegativeButton(getContext().getString(com.tungsten.fcllibrary.R.string.dialog_positive), null);
builder.create().show();
} else {
if (executor.getException() == null)
return;
alertFailureMessage(getContext(), executor.getException(), () -> {});
}
});
}
});
TaskDialog dialog = new TaskDialog(getContext(), TaskCancellationAction.NO_CANCEL);
dialog.setTitle(getContext().getString(R.string.install_installer_install_offline));
dialog.setExecutor(executor);
dialog.show();
executor.start();
}
private void clear() {
if (parent == null) {
parent = new LinearLayoutCompat(getContext());
parent.setOrientation(LinearLayoutCompat.VERTICAL);
scrollView.addView(parent);
ViewGroup.LayoutParams layoutParams = scrollView.getChildAt(0).getLayoutParams();
layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
scrollView.getChildAt(0).setLayoutParams(layoutParams);
}
parent.removeAllViews();
}
private void addView(InstallerItem installerItem) {
if (parent == null) {
parent = new LinearLayoutCompat(getContext());
parent.setOrientation(LinearLayoutCompat.VERTICAL);
scrollView.addView(parent);
ViewGroup.LayoutParams layoutParams = scrollView.getChildAt(0).getLayoutParams();
layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
scrollView.getChildAt(0).setLayoutParams(layoutParams);
}
View view = installerItem.createView();
if (parent.getChildCount() > 0) {
view.setPadding(0, ConvertUtils.dip2px(getContext(), 10), 0, 0);
}
parent.addView(view);
}
private void finish(Profile profile, RemoteVersion remoteVersion) {
// We remove library but not save it,
// so if installation failed will not break down current version.
Task<Version> ret = Task.supplyAsync(() -> version);
List<String> stages = new ArrayList<>();
ret = ret.thenComposeAsync(version -> profile.getDependency(DownloadProviders.getDownloadProvider()).installLibraryAsync(version, remoteVersion));
stages.add(String.format("fcl.install.%s:%s", remoteVersion.getLibraryId(), remoteVersion.getSelfVersion()));
Task<?> task = ret.thenComposeAsync(profile.getRepository()::saveAsync).thenComposeAsync(profile.getRepository().refreshVersionsAsync()).withStagesHint(stages);
TaskDialog pane = new TaskDialog(getContext(), new TaskCancellationAction(AppCompatDialog::dismiss));
pane.setTitle(getContext().getString(R.string.install_change_version));
Schedulers.androidUIThread().execute(() -> {
TaskExecutor executor = task.executor(new TaskListener() {
@Override
public void onStop(boolean success, TaskExecutor executor) {
Schedulers.androidUIThread().execute(() -> {
if (success) {
FCLAlertDialog.Builder builder1 = new FCLAlertDialog.Builder(getContext());
builder1.setAlertLevel(FCLAlertDialog.AlertLevel.INFO);
builder1.setCancelable(false);
builder1.setMessage(getContext().getString(R.string.install_success));
builder1.setNegativeButton(getContext().getString(com.tungsten.fcllibrary.R.string.dialog_positive), () -> ManagePageManager.getInstance().dismissCurrentTempPage());
builder1.create().show();
} else {
if (executor.getException() == null)
return;
alertFailureMessage(getContext(), executor.getException(), () -> {});
}
});
}
});
pane.setExecutor(executor);
pane.show();
executor.start();
});
}
}

View File

@ -18,6 +18,7 @@ import com.tungsten.fclcore.game.GameRepository;
import com.tungsten.fclcore.task.Schedulers;
import com.tungsten.fclcore.task.Task;
import com.tungsten.fcllibrary.component.ui.FCLBasePage;
import com.tungsten.fcllibrary.component.ui.FCLCommonPage;
import com.tungsten.fcllibrary.component.ui.FCLMultiPageUI;
import com.tungsten.fcllibrary.component.view.FCLTabLayout;
import com.tungsten.fcllibrary.component.view.FCLUILayout;
@ -55,6 +56,9 @@ public class ManageUI extends FCLMultiPageUI implements TabLayout.OnTabSelectedL
@Override
public void onStart() {
super.onStart();
for (FCLCommonPage page : pageManager.getAllPages()) {
((VersionLoadable) page).loadVersion(getProfile(), getVersion());
}
}
@Override
@ -171,6 +175,7 @@ public class ManageUI extends FCLMultiPageUI implements TabLayout.OnTabSelectedL
setVersion(version, profile);
preferredVersionName = version;
pageManager.dismissAllTempPages();
pageManager.loadVersion(profile, version);
}

View File

@ -9,4 +9,8 @@ public class RequestCodes {
public static final int SELECT_PROFILE_CODE = 100;
public static final int SELECT_SKIN_CODE = 150;
public static final int SELECT_AUTO_INSTALLER_CODE = 200;
public static final int SELECT_MANUAL_INSTALLER_CODE = 250;
}

View File

@ -1,7 +1,19 @@
<?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:paddingStart="10dp"
android:paddingEnd="10dp"
android:paddingTop="10dp"
android:background="@color/ui_bg_color"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:id="@+id/scroll"
android:layout_marginTop="10dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_width="match_parent"
android:layout_height="0dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>