diff --git a/app/src/main/java/org/lsposed/manager/ConfigManager.java b/app/src/main/java/org/lsposed/manager/ConfigManager.java index 36051ebd..5def8309 100644 --- a/app/src/main/java/org/lsposed/manager/ConfigManager.java +++ b/app/src/main/java/org/lsposed/manager/ConfigManager.java @@ -240,7 +240,7 @@ public class ConfigManager { } public static boolean installExistingPackageAsUser(String packageName, int userId) { - int INSTALL_SUCCEEDED = 1; + final int INSTALL_SUCCEEDED = 1; try { var ret = LSPManagerServiceClient.installExistingPackageAsUser(packageName, userId); return ret == INSTALL_SUCCEEDED; diff --git a/app/src/main/java/org/lsposed/manager/adapters/ScopeAdapter.java b/app/src/main/java/org/lsposed/manager/adapters/ScopeAdapter.java index 5064259f..e0f46ffe 100644 --- a/app/src/main/java/org/lsposed/manager/adapters/ScopeAdapter.java +++ b/app/src/main/java/org/lsposed/manager/adapters/ScopeAdapter.java @@ -43,7 +43,6 @@ import android.text.style.ForegroundColorSpan; import android.text.style.StyleSpan; import android.text.style.TypefaceSpan; import android.util.Log; -import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; @@ -60,6 +59,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.widget.SearchView; +import androidx.constraintlayout.widget.ConstraintLayout; import androidx.recyclerview.widget.RecyclerView; import com.bumptech.glide.request.target.CustomTarget; @@ -72,6 +72,7 @@ import org.lsposed.manager.App; import org.lsposed.manager.BuildConfig; import org.lsposed.manager.ConfigManager; import org.lsposed.manager.R; +import org.lsposed.manager.databinding.ItemModuleBinding; import org.lsposed.manager.ui.activity.AppListActivity; import org.lsposed.manager.ui.fragment.CompileDialogFragment; import org.lsposed.manager.util.GlideApp; @@ -149,8 +150,7 @@ public class ScopeAdapter extends RecyclerView.Adapter @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - View v = LayoutInflater.from(activity).inflate(R.layout.item_module, parent, false); - return new ViewHolder(v); + return new ViewHolder(ItemModuleBinding.inflate(activity.getLayoutInflater(), parent, false)); } private boolean shouldHideApp(PackageInfo info, ApplicationWithEquals app) { @@ -559,20 +559,19 @@ public class ScopeAdapter extends RecyclerView.Adapter } static class ViewHolder extends RecyclerView.ViewHolder { - - View root; + ConstraintLayout root; ImageView appIcon; TextView appName; TextView appDescription; MaterialCheckBox checkbox; - ViewHolder(View itemView) { - super(itemView); - root = itemView.findViewById(R.id.item_root); - appIcon = itemView.findViewById(R.id.app_icon); - appName = itemView.findViewById(R.id.app_name); - appDescription = itemView.findViewById(R.id.description); - checkbox = itemView.findViewById(R.id.checkbox); + ViewHolder(ItemModuleBinding binding) { + super(binding.getRoot()); + root = binding.itemRoot; + appIcon = binding.appIcon; + appName = binding.appName; + appDescription = binding.description; + checkbox = binding.checkbox; checkbox.setVisibility(View.VISIBLE); } } diff --git a/app/src/main/java/org/lsposed/manager/ui/activity/ModulesActivity.java b/app/src/main/java/org/lsposed/manager/ui/activity/ModulesActivity.java index 678c1759..098d6c7c 100644 --- a/app/src/main/java/org/lsposed/manager/ui/activity/ModulesActivity.java +++ b/app/src/main/java/org/lsposed/manager/ui/activity/ModulesActivity.java @@ -41,7 +41,6 @@ import android.text.TextUtils; import android.text.style.ForegroundColorSpan; import android.text.style.StyleSpan; import android.text.style.TypefaceSpan; -import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; @@ -57,6 +56,7 @@ import androidx.annotation.Nullable; import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.widget.SearchView; +import androidx.constraintlayout.widget.ConstraintLayout; import androidx.core.content.ContextCompat; import androidx.lifecycle.Lifecycle; import androidx.recyclerview.widget.RecyclerView; @@ -64,6 +64,8 @@ import androidx.viewpager2.widget.ViewPager2; import com.bumptech.glide.request.target.CustomTarget; import com.bumptech.glide.request.transition.Transition; +import com.google.android.material.checkbox.MaterialCheckBox; +import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.snackbar.Snackbar; import com.google.android.material.tabs.TabLayoutMediator; @@ -71,6 +73,7 @@ import org.lsposed.manager.ConfigManager; import org.lsposed.manager.R; import org.lsposed.manager.adapters.AppHelper; import org.lsposed.manager.databinding.ActivityModuleDetailBinding; +import org.lsposed.manager.databinding.ItemModuleBinding; import org.lsposed.manager.databinding.ItemRepoRecyclerviewBinding; import org.lsposed.manager.repo.RepoLoader; import org.lsposed.manager.ui.activity.base.BaseActivity; @@ -83,6 +86,7 @@ import java.util.ArrayList; import java.util.Comparator; import java.util.HashMap; import java.util.List; +import java.util.function.Predicate; import java.util.stream.Collectors; import rikka.core.res.ResourcesKt; @@ -133,8 +137,31 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi if (recyclerView != null) { binding.appBar.setRaised(!recyclerView.getBorderViewDelegate().isShowingTopBorder()); } + if (position > 0) binding.fab.show(); + else binding.fab.hide(); } }); + binding.fab.setOnClickListener(view -> { + var pickAdaptor = new ModuleAdapter(0, null, true); + var position = binding.viewPager.getCurrentItem(); + var snapshot = adapters.get(position).snapshot().stream().map(m -> m.packageName).collect(Collectors.toSet()); + var userId = adapters.get(position).getUserId(); + pickAdaptor.setFilter(m -> !snapshot.contains(m.packageName)); + pickAdaptor.refresh(); + var v = new RecyclerView(ModulesActivity.this); + v.setAdapter(pickAdaptor); + v.setLayoutManager(new LinearLayoutManagerFix(ModulesActivity.this)); + var dialog = new AlertDialog.Builder(ModulesActivity.this) + .setTitle(getString(R.string.install_to_user, userId)) + .setView(v) + .setNegativeButton(android.R.string.cancel, null) + .show(); + pickAdaptor.setOnPickListener(picked -> { + var module = (ModuleUtil.InstalledModule) picked.getTag(); + installModuleToUser(module, userId); + dialog.dismiss(); + }); + }); mSearchListener = new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String query) { @@ -191,12 +218,6 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi ArrayList titles = new ArrayList<>(); for (int userId : userIds) { var adapter = new ModuleAdapter(userId, handles.get(userId)); - if (userId == 0) { - adapter.setProfiles(users.stream() - .filter(u -> u.hashCode() != 0) - .mapToInt(UserHandle::hashCode) - .toArray()); - } adapter.setHasStableIds(true); adapters.add(adapter); titles.add(getString(R.string.user_title, userId)); @@ -244,6 +265,28 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi return super.onOptionsItemSelected(item); } + private void installModuleToUser(ModuleUtil.InstalledModule module, int userId) { + new AlertDialog.Builder(this) + .setTitle(getString(R.string.install_to_user, userId)) + .setMessage(getString(R.string.install_to_user_message, module.getAppName(), userId)) + .setPositiveButton(android.R.string.ok, (dialog, which) -> + workHandler.post(() -> { + var success = ConfigManager.installExistingPackageAsUser(module.packageName, userId); + runOnUiThread(() -> { + String text = success ? getString(R.string.module_installed, module.getAppName(), userId) : getString(R.string.module_install_failed); + if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.RESUMED)) { + Snackbar.make(binding.snackbar, text, Snackbar.LENGTH_SHORT).show(); + } else { + Toast.makeText(ModulesActivity.this, text, Toast.LENGTH_SHORT).show(); + } + }); + if (success) + moduleUtil.reloadSingleModule(module.packageName, userId); + })) + .setNegativeButton(android.R.string.cancel, null) + .show(); + } + @Override public boolean onContextItemSelected(@NonNull MenuItem item) { ModuleUtil.InstalledModule module = ModuleUtil.getInstance().getModule(selectedModule.packageName, selectedModule.userId); @@ -305,25 +348,7 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi startActivity(intent); return true; } else if (item.getGroupId() == 1) { - new AlertDialog.Builder(this) - .setTitle(getString(R.string.install_to_user, itemId)) - .setMessage(getString(R.string.install_to_user_message, module.getAppName(), itemId)) - .setPositiveButton(android.R.string.ok, (dialog, which) -> - workHandler.post(() -> { - var success = ConfigManager.installExistingPackageAsUser(module.packageName, itemId); - runOnUiThread(() -> { - String text = success ? getString(R.string.module_installed, module.getAppName()) : getString(R.string.module_install_failed); - if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.RESUMED)) { - Snackbar.make(binding.snackbar, text, Snackbar.LENGTH_SHORT).show(); - } else { - Toast.makeText(ModulesActivity.this, text, Toast.LENGTH_SHORT).show(); - } - }); - if (success) - moduleUtil.reloadSingleModule(module.packageName, itemId); - })) - .setNegativeButton(android.R.string.cancel, null) - .show(); + installModuleToUser(module, itemId); return true; } return super.onContextItemSelected(item); @@ -334,7 +359,7 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi @NonNull @Override public PagerAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - return new PagerAdapter.ViewHolder(ItemRepoRecyclerviewBinding.inflate(getLayoutInflater(), parent, false).getRoot()); + return new PagerAdapter.ViewHolder(ItemRepoRecyclerviewBinding.inflate(getLayoutInflater(), parent, false)); } @Override @@ -357,10 +382,11 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi class ViewHolder extends RecyclerView.ViewHolder { BorderRecyclerView recyclerView; + FloatingActionButton btn; - public ViewHolder(@NonNull View itemView) { - super(itemView); - recyclerView = itemView.findViewById(R.id.recyclerView); + public ViewHolder(@NonNull ItemRepoRecyclerviewBinding binding) { + super(binding.getRoot()); + recyclerView = binding.recyclerView; } } } @@ -370,29 +396,35 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi private final List showList = new ArrayList<>(); private final int userId; private final UserHandle userHandle; + private final boolean isPick; private boolean isLoaded; - private int[] profiles = new int[0]; + private View.OnClickListener onPickListener; + + private Predicate customFilter = m -> true; ModuleAdapter(int userId, UserHandle userHandle) { - this.userId = userId; - this.userHandle = userHandle; + this(userId, userHandle, false); } - public void setProfiles(int[] profiles) { - this.profiles = profiles; + ModuleAdapter(int userId, UserHandle userHandle, boolean isPick) { + this.userId = userId; + this.userHandle = userHandle; + this.isPick = isPick; + } + + public int getUserId() { + return userId; } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_module, parent, false); - return new ViewHolder(v); + return new ViewHolder(ItemModuleBinding.inflate(getLayoutInflater(), parent, false)); } @Override public void onBindViewHolder(@NonNull ViewHolder holder, int position) { ModuleUtil.InstalledModule item = showList.get(position); - holder.root.setAlpha(moduleUtil.isModuleEnabled(item.packageName) ? 1.0f : .5f); String appName; if (item.userId != 0) { appName = String.format("%s (%s)", item.getAppName(), item.userId); @@ -460,7 +492,7 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi menu.removeItem(R.id.menu_app_info); } if (item.userId == 0) { - for (int profile : profiles) { + for (int profile : ConfigManager.getUsers()) { if (ModuleUtil.getInstance().getModule(item.packageName, profile) == null) { menu.add(1, profile, 0, getString(R.string.install_to_user, profile)); } @@ -468,23 +500,30 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi } }); - holder.itemView.setOnClickListener(v -> { - Intent intent = new Intent(ModulesActivity.this, AppListActivity.class); - intent.putExtra("modulePackageName", item.packageName); - intent.putExtra("moduleUserId", item.userId); - intent.putExtra("userHandle", userHandle); - startActivity(intent); - }); + if (!isPick) { + holder.root.setAlpha(moduleUtil.isModuleEnabled(item.packageName) ? 1.0f : .5f); + holder.itemView.setOnClickListener(v -> { + Intent intent = new Intent(ModulesActivity.this, AppListActivity.class); + intent.putExtra("modulePackageName", item.packageName); + intent.putExtra("moduleUserId", item.userId); + intent.putExtra("userHandle", userHandle); + startActivity(intent); + }); - holder.itemView.setOnLongClickListener(v -> { - selectedModule = item; - selectedModuleUser = userHandle; - return false; - }); - - holder.appVersion.setVisibility(View.VISIBLE); - holder.appVersion.setText(item.versionName); - holder.appVersion.setSelected(true); + holder.itemView.setOnLongClickListener(v -> { + selectedModule = item; + selectedModuleUser = userHandle; + return false; + }); + holder.appVersion.setVisibility(View.VISIBLE); + holder.appVersion.setText(item.versionName); + holder.appVersion.setSelected(true); + } else { + holder.itemView.setTag(item); + holder.itemView.setOnClickListener(v -> { + if (onPickListener != null) onPickListener.onClick(v); + }); + } } @Override @@ -503,6 +542,20 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi return new ApplicationFilter(); } + public void setFilter(@NonNull Predicate filter) { + this.customFilter = filter; + } + + public void setOnPickListener(View.OnClickListener onPickListener) { + this.onPickListener = onPickListener; + } + + public List snapshot() { + List list = new ArrayList<>(); + list.addAll(searchList); + return list; + } + public void refresh() { refresh(false); } @@ -515,7 +568,7 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi private final Runnable reloadModules = new Runnable() { public void run() { searchList.clear(); - searchList.addAll(moduleUtil.getModules().values().stream().filter(module -> module.userId == userId).collect(Collectors.toList())); + searchList.addAll(moduleUtil.getModules().values().stream().filter(module -> module.userId == userId).filter(customFilter).collect(Collectors.toList())); Comparator cmp = AppHelper.getAppListComparator(0, pm); searchList.sort((a, b) -> { boolean aChecked = moduleUtil.isModuleEnabled(a.packageName); @@ -539,21 +592,21 @@ public class ModulesActivity extends BaseActivity implements ModuleUtil.ModuleLi } class ViewHolder extends RecyclerView.ViewHolder { - View root; + ConstraintLayout root; ImageView appIcon; TextView appName; TextView appDescription; TextView appVersion; - TextView warningText; + MaterialCheckBox checkBox; - ViewHolder(View itemView) { - super(itemView); - root = itemView.findViewById(R.id.item_root); - appIcon = itemView.findViewById(R.id.app_icon); - appName = itemView.findViewById(R.id.app_name); - appDescription = itemView.findViewById(R.id.description); - appVersion = itemView.findViewById(R.id.version_name); - warningText = itemView.findViewById(R.id.warning); + ViewHolder(ItemModuleBinding binding) { + super(binding.getRoot()); + root = binding.itemRoot; + appIcon = binding.appIcon; + appName = binding.appName; + appDescription = binding.description; + appVersion = binding.versionName; + checkBox = binding.checkbox; } } diff --git a/app/src/main/java/org/lsposed/manager/ui/activity/RepoActivity.java b/app/src/main/java/org/lsposed/manager/ui/activity/RepoActivity.java index 661939fc..c15b97aa 100644 --- a/app/src/main/java/org/lsposed/manager/ui/activity/RepoActivity.java +++ b/app/src/main/java/org/lsposed/manager/ui/activity/RepoActivity.java @@ -24,10 +24,8 @@ import android.content.Intent; import android.os.Bundle; import android.text.SpannableStringBuilder; import android.text.TextUtils; -import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; -import android.view.View; import android.view.ViewGroup; import android.widget.Filter; import android.widget.TextView; @@ -35,6 +33,7 @@ import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.constraintlayout.widget.ConstraintLayout; import androidx.lifecycle.Lifecycle; import androidx.recyclerview.widget.RecyclerView; @@ -42,6 +41,7 @@ import com.google.android.material.snackbar.Snackbar; import org.lsposed.manager.ConfigManager; import org.lsposed.manager.R; +import org.lsposed.manager.databinding.ItemOnlinemoduleBinding; import org.lsposed.manager.repo.RepoLoader; import org.lsposed.manager.repo.model.OnlineModule; import org.lsposed.manager.ui.activity.base.ListActivity; @@ -148,8 +148,7 @@ public class RepoActivity extends ListActivity implements RepoLoader.Listener { @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_onlinemodule, parent, false); - return new ViewHolder(v); + return new ViewHolder(ItemOnlinemoduleBinding.inflate(getLayoutInflater(), parent, false)); } @Override @@ -211,15 +210,15 @@ public class RepoActivity extends ListActivity implements RepoLoader.Listener { } class ViewHolder extends RecyclerView.ViewHolder { - View root; + ConstraintLayout root; TextView appName; TextView appDescription; - ViewHolder(View itemView) { - super(itemView); - root = itemView.findViewById(R.id.item_root); - appName = itemView.findViewById(R.id.app_name); - appDescription = itemView.findViewById(R.id.description); + ViewHolder(ItemOnlinemoduleBinding binding) { + super(binding.getRoot()); + root = binding.itemRoot; + appName = binding.appName; + appDescription = binding.description; } } diff --git a/app/src/main/java/org/lsposed/manager/ui/activity/RepoItemActivity.java b/app/src/main/java/org/lsposed/manager/ui/activity/RepoItemActivity.java index 3ddd9a94..d655fc92 100644 --- a/app/src/main/java/org/lsposed/manager/ui/activity/RepoItemActivity.java +++ b/app/src/main/java/org/lsposed/manager/ui/activity/RepoItemActivity.java @@ -40,6 +40,7 @@ import androidx.lifecycle.Lifecycle; import androidx.recyclerview.widget.RecyclerView; import androidx.viewpager2.widget.ViewPager2; +import com.google.android.material.button.MaterialButton; import com.google.android.material.progressindicator.CircularProgressIndicator; import com.google.android.material.snackbar.Snackbar; import com.google.android.material.tabs.TabLayoutMediator; @@ -282,9 +283,9 @@ public class RepoItemActivity extends BaseActivity implements RepoLoader.Listene @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { if (viewType == 0) { - return new ViewHolder(ItemRepoReleaseBinding.inflate(getLayoutInflater(), parent, false).getRoot()); + return new ReleaseViewHolder(ItemRepoReleaseBinding.inflate(getLayoutInflater(), parent, false)); } else { - return new ViewHolder(ItemRepoLoadmoreBinding.inflate(getLayoutInflater(), parent, false).getRoot()); + return new LoadmoreViewHolder(ItemRepoLoadmoreBinding.inflate(getLayoutInflater(), parent, false)); } } @@ -344,17 +345,30 @@ public class RepoItemActivity extends BaseActivity implements RepoLoader.Listene class ViewHolder extends RecyclerView.ViewHolder { TextView title; LinkifyTextView description; - View openInBrowser; - View viewAssets; + MaterialButton openInBrowser; + MaterialButton viewAssets; CircularProgressIndicator progress; - public ViewHolder(View view) { - super(view); - title = view.findViewById(R.id.title); - description = view.findViewById(R.id.description); - openInBrowser = view.findViewById(R.id.open_in_browser); - viewAssets = view.findViewById(R.id.view_assets); - progress = view.findViewById(R.id.progress); + public ViewHolder(@NonNull View itemView) { + super(itemView); + } + } + + class ReleaseViewHolder extends ViewHolder { + public ReleaseViewHolder(ItemRepoReleaseBinding binding) { + super(binding.getRoot()); + title = binding.title; + description = binding.description; + openInBrowser = binding.openInBrowser; + viewAssets = binding.viewAssets; + } + } + + class LoadmoreViewHolder extends ViewHolder { + public LoadmoreViewHolder(ItemRepoLoadmoreBinding binding) { + super(binding.getRoot()); + title = binding.title; + progress = binding.progress; } } } @@ -365,9 +379,9 @@ public class RepoItemActivity extends BaseActivity implements RepoLoader.Listene @Override public PagerAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { if (viewType == 0) { - return new ViewHolder(ItemRepoReadmeBinding.inflate(getLayoutInflater(), parent, false).getRoot(), viewType); + return new ReadmeViewHolder(ItemRepoReadmeBinding.inflate(getLayoutInflater(), parent, false)); } else { - return new ViewHolder(ItemRepoRecyclerviewBinding.inflate(getLayoutInflater(), parent, false).getRoot(), viewType); + return new RecyclerviewBinding(ItemRepoRecyclerviewBinding.inflate(getLayoutInflater(), parent, false)); } } @@ -411,14 +425,23 @@ public class RepoItemActivity extends BaseActivity implements RepoLoader.Listene BorderNestedScrollView scrollView; BorderRecyclerView recyclerView; - public ViewHolder(@NonNull View itemView, int viewType) { + public ViewHolder(@NonNull View itemView) { super(itemView); - if (viewType == 0) { - textView = itemView.findViewById(R.id.readme); - scrollView = itemView.findViewById(R.id.scrollView); - } else { - recyclerView = itemView.findViewById(R.id.recyclerView); - } + } + } + + class ReadmeViewHolder extends ViewHolder { + public ReadmeViewHolder(ItemRepoReadmeBinding binding) { + super(binding.getRoot()); + textView = binding.readme; + scrollView = binding.scrollView; + } + } + + class RecyclerviewBinding extends ViewHolder { + public RecyclerviewBinding(ItemRepoRecyclerviewBinding binding) { + super(binding.getRoot()); + recyclerView = binding.recyclerView; } } } diff --git a/app/src/main/res/drawable/ic_baseline_add_24.xml b/app/src/main/res/drawable/ic_baseline_add_24.xml new file mode 100644 index 00000000..eb232541 --- /dev/null +++ b/app/src/main/res/drawable/ic_baseline_add_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/activity_module_detail.xml b/app/src/main/res/layout/activity_module_detail.xml index 07252b1e..2022a9ac 100644 --- a/app/src/main/res/layout/activity_module_detail.xml +++ b/app/src/main/res/layout/activity_module_detail.xml @@ -59,4 +59,15 @@ android:id="@+id/view_pager" android:layout_width="match_parent" android:layout_height="match_parent" /> + + diff --git a/app/src/main/res/layout/item_repo_recyclerview.xml b/app/src/main/res/layout/item_repo_recyclerview.xml index d30b7618..3499e94d 100644 --- a/app/src/main/res/layout/item_repo_recyclerview.xml +++ b/app/src/main/res/layout/item_repo_recyclerview.xml @@ -17,8 +17,8 @@ ~ Copyright (C) 2020 EdXposed Contributors ~ Copyright (C) 2021 LSPosed Contributors --> - -用户 %d 安装到用户 %d 要安装 %1$s 到用户 %2$d 吗?建议手动安装或多开,通过 LSPosed 强制安装可能会出现问题。 - 已安装 %1$s + 已安装 %1$s 到用户 %2$d 安装失败 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 74cb8847..bec8b685 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -85,11 +85,11 @@ Do you want to uninstall this module? Uninstalled %1$s Uninstall unsuccessful + Added %1$s to user %2$d + Adding module failed User %d Install to user %d Want to install %1$s to user %2$d? It is recommended to install manually, forcing installation via LSPosed may cause problems. - %1$s installed - install failed Re-optimize @@ -185,4 +185,5 @@ LSPosed]]> Copied ¯\\\\_(ツ)_\/¯\nNothing here + Add module to user