mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-28 04:25:27 +00:00
Updated Magisk fragment to Kotlin
Exported old update card to special xml include where binding takes care of everything that had to be done in code beforehand. Added several easing functions and enums. Backported some classes and functions from the old fork Expect major breakage. Literally nothing works as the functionality needs to be implemented
This commit is contained in:
parent
f309522268
commit
bd00ae8ede
@ -2,10 +2,12 @@ package com.topjohnwu.magisk.di
|
||||
|
||||
import android.content.Context
|
||||
import com.skoumal.teanity.rxbus.RxBus
|
||||
import com.topjohnwu.magisk.App
|
||||
import org.koin.dsl.module
|
||||
|
||||
|
||||
val applicationModule = module {
|
||||
single { RxBus() }
|
||||
single { get<Context>().resources }
|
||||
single { get<Context>() as App }
|
||||
}
|
||||
|
@ -1,10 +1,12 @@
|
||||
package com.topjohnwu.magisk.di
|
||||
|
||||
import com.topjohnwu.magisk.ui.MainViewModel
|
||||
import com.topjohnwu.magisk.ui.home.HomeViewModel
|
||||
import org.koin.androidx.viewmodel.dsl.viewModel
|
||||
import org.koin.dsl.module
|
||||
|
||||
|
||||
val viewModelModules = module {
|
||||
viewModel { MainViewModel() }
|
||||
viewModel { HomeViewModel(get(), get()) }
|
||||
}
|
||||
|
@ -0,0 +1,14 @@
|
||||
package com.topjohnwu.magisk.model.events
|
||||
|
||||
import com.skoumal.teanity.viewevents.ViewEvent
|
||||
|
||||
|
||||
data class OpenLinkEvent(val url: String) : ViewEvent()
|
||||
|
||||
object ManagerInstallEvent : ViewEvent()
|
||||
object MagiskInstallEvent : ViewEvent()
|
||||
|
||||
object ManagerChangelogEvent : ViewEvent()
|
||||
object MagiskChangelogEvent : ViewEvent()
|
||||
|
||||
object UninstallEvent : ViewEvent()
|
@ -0,0 +1,31 @@
|
||||
package com.topjohnwu.magisk.model.observer
|
||||
|
||||
import androidx.databinding.Observable
|
||||
import androidx.databinding.ObservableField
|
||||
import java.io.Serializable
|
||||
|
||||
|
||||
class Observer<T>(vararg dependencies: Observable, private val observer: () -> T) :
|
||||
ObservableField<T>(*dependencies), Serializable {
|
||||
|
||||
val value: T get() = observer()
|
||||
|
||||
@Deprecated(
|
||||
message = "Use KObservableField.value syntax from code",
|
||||
replaceWith = ReplaceWith("value")
|
||||
)
|
||||
override fun get(): T {
|
||||
return value
|
||||
}
|
||||
|
||||
@Deprecated(
|
||||
message = "Observer cannot be set",
|
||||
level = DeprecationLevel.HIDDEN
|
||||
)
|
||||
override fun set(newValue: T) {
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "Observer(value=$value)"
|
||||
}
|
||||
}
|
@ -1,8 +1,14 @@
|
||||
package com.topjohnwu.magisk.ui.base
|
||||
|
||||
import androidx.core.net.toUri
|
||||
import androidx.databinding.ViewDataBinding
|
||||
import com.skoumal.teanity.view.TeanityActivity
|
||||
import com.topjohnwu.magisk.utils.Utils
|
||||
|
||||
|
||||
abstract class MagiskActivity<ViewModel : MagiskViewModel, Binding : ViewDataBinding> :
|
||||
TeanityActivity<ViewModel, Binding>()
|
||||
TeanityActivity<ViewModel, Binding>() {
|
||||
|
||||
fun openUrl(url: String) = Utils.openLink(this, url.toUri())
|
||||
|
||||
}
|
||||
|
@ -5,4 +5,12 @@ import com.skoumal.teanity.view.TeanityFragment
|
||||
|
||||
|
||||
abstract class MagiskFragment<ViewModel : MagiskViewModel, Binding : ViewDataBinding> :
|
||||
TeanityFragment<ViewModel, Binding>()
|
||||
TeanityFragment<ViewModel, Binding>() {
|
||||
|
||||
protected val magiskActivity get() = activity as MagiskActivity<*, *>
|
||||
|
||||
fun openLink(url: String) {
|
||||
magiskActivity.openUrl(url)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package com.topjohnwu.magisk.ui.base
|
||||
|
||||
import com.skoumal.teanity.viewmodel.TeanityViewModel
|
||||
import com.skoumal.teanity.viewmodel.LoadingViewModel
|
||||
|
||||
|
||||
abstract class MagiskViewModel : TeanityViewModel()
|
||||
abstract class MagiskViewModel : LoadingViewModel()
|
||||
|
@ -0,0 +1,91 @@
|
||||
package com.topjohnwu.magisk.ui.home
|
||||
|
||||
import android.content.res.Resources
|
||||
import com.skoumal.teanity.util.KObservableField
|
||||
import com.topjohnwu.magisk.App
|
||||
import com.topjohnwu.magisk.Config
|
||||
import com.topjohnwu.magisk.Const
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.model.events.*
|
||||
import com.topjohnwu.magisk.model.observer.Observer
|
||||
import com.topjohnwu.magisk.ui.base.MagiskViewModel
|
||||
import com.topjohnwu.magisk.utils.toggle
|
||||
|
||||
|
||||
class HomeViewModel(
|
||||
private val resources: Resources,
|
||||
private val app: App
|
||||
) : MagiskViewModel() {
|
||||
|
||||
val isAdvancedExpanded = KObservableField(false)
|
||||
|
||||
val isForceEncryption = KObservableField(false /*todo*/)
|
||||
val isKeepVerity = KObservableField(false /*todo*/)
|
||||
|
||||
private val prefsObserver = Observer(isForceEncryption, isKeepVerity) {
|
||||
Config.keepEnc = isForceEncryption.value
|
||||
Config.keepVerity = isKeepVerity.value
|
||||
}
|
||||
|
||||
val magiskState = KObservableField(MagiskState.LOADING)
|
||||
val magiskStateText = Observer(magiskState) {
|
||||
@Suppress("WhenWithOnlyElse")
|
||||
when (magiskState.value) {
|
||||
MagiskState.NO_ROOT -> TODO()
|
||||
MagiskState.NOT_INSTALLED -> TODO()
|
||||
MagiskState.UP_TO_DATE -> TODO()
|
||||
MagiskState.LOADING -> TODO()
|
||||
MagiskState.OBSOLETE -> TODO()
|
||||
}
|
||||
}
|
||||
val magiskCurrentVersion = KObservableField("")
|
||||
val magiskLatestVersion = KObservableField("")
|
||||
val magiskAdditionalInfo = Observer(magiskState) {
|
||||
if (Config.get<Boolean>(Config.Key.COREONLY))
|
||||
resources.getString(R.string.core_only_enabled)
|
||||
else
|
||||
""
|
||||
}
|
||||
|
||||
val managerState = KObservableField(MagiskState.LOADING)
|
||||
val managerStateText = Observer(managerState) {
|
||||
@Suppress("WhenWithOnlyElse")
|
||||
when (managerState.value) {
|
||||
MagiskState.NO_ROOT -> TODO()
|
||||
MagiskState.NOT_INSTALLED -> TODO()
|
||||
MagiskState.UP_TO_DATE -> TODO()
|
||||
MagiskState.LOADING -> TODO()
|
||||
MagiskState.OBSOLETE -> TODO()
|
||||
}
|
||||
}
|
||||
val managerCurrentVersion = KObservableField("")
|
||||
val managerLatestVersion = KObservableField("")
|
||||
val managerAdditionalInfo = Observer(managerState) {
|
||||
if (app.packageName != BuildConfig.APPLICATION_ID)
|
||||
"(${app.packageName})"
|
||||
else
|
||||
""
|
||||
}
|
||||
|
||||
fun paypalPressed() = OpenLinkEvent(Const.Url.PAYPAL_URL).publish()
|
||||
fun patreonPressed() = OpenLinkEvent(Const.Url.PATREON_URL).publish()
|
||||
fun twitterPressed() = OpenLinkEvent(Const.Url.TWITTER_URL).publish()
|
||||
fun githubPressed() = OpenLinkEvent(Const.Url.REPO_URL).publish()
|
||||
fun xdaPressed() = OpenLinkEvent(Const.Url.XDA_THREAD).publish()
|
||||
fun uninstallPressed() = UninstallEvent.publish()
|
||||
|
||||
fun refresh() {}
|
||||
|
||||
fun advancedPressed() = isAdvancedExpanded.toggle()
|
||||
|
||||
fun installPressed(item: MagiskItem) = when (item) {
|
||||
MagiskItem.MANAGER -> ManagerInstallEvent.publish()
|
||||
MagiskItem.MAGISK -> MagiskInstallEvent.publish()
|
||||
}
|
||||
|
||||
fun cardPressed(item: MagiskItem) = when (item) {
|
||||
MagiskItem.MANAGER -> ManagerChangelogEvent.publish()
|
||||
MagiskItem.MAGISK -> MagiskChangelogEvent.publish()
|
||||
}
|
||||
|
||||
}
|
@ -1,332 +0,0 @@
|
||||
package com.topjohnwu.magisk.ui.home;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.topjohnwu.magisk.BuildConfig;
|
||||
import com.topjohnwu.magisk.Config;
|
||||
import com.topjohnwu.magisk.Const;
|
||||
import com.topjohnwu.magisk.R;
|
||||
import com.topjohnwu.magisk.tasks.CheckUpdates;
|
||||
import com.topjohnwu.magisk.ui.MainActivity;
|
||||
import com.topjohnwu.magisk.ui.base.BaseActivity;
|
||||
import com.topjohnwu.magisk.ui.base.BaseFragment;
|
||||
import com.topjohnwu.magisk.utils.Event;
|
||||
import com.topjohnwu.magisk.utils.Utils;
|
||||
import com.topjohnwu.magisk.view.ArrowExpandable;
|
||||
import com.topjohnwu.magisk.view.Expandable;
|
||||
import com.topjohnwu.magisk.view.ExpandableViewHolder;
|
||||
import com.topjohnwu.magisk.view.MarkDownWindow;
|
||||
import com.topjohnwu.magisk.view.SafetyNet;
|
||||
import com.topjohnwu.magisk.view.UpdateCardHolder;
|
||||
import com.topjohnwu.magisk.view.dialogs.EnvFixDialog;
|
||||
import com.topjohnwu.magisk.view.dialogs.MagiskInstallDialog;
|
||||
import com.topjohnwu.magisk.view.dialogs.ManagerInstallDialog;
|
||||
import com.topjohnwu.magisk.view.dialogs.UninstallDialog;
|
||||
import com.topjohnwu.net.Networking;
|
||||
import com.topjohnwu.superuser.Shell;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.cardview.widget.CardView;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
import androidx.transition.ChangeBounds;
|
||||
import androidx.transition.Fade;
|
||||
import androidx.transition.Transition;
|
||||
import androidx.transition.TransitionManager;
|
||||
import androidx.transition.TransitionSet;
|
||||
import butterknife.BindColor;
|
||||
import butterknife.BindView;
|
||||
import butterknife.OnClick;
|
||||
|
||||
public class MagiskFragment extends BaseFragment implements SwipeRefreshLayout.OnRefreshListener {
|
||||
|
||||
private static boolean shownDialog = false;
|
||||
|
||||
@BindView(R.id.swipeRefreshLayout) SwipeRefreshLayout mSwipeRefreshLayout;
|
||||
@BindView(R.id.linearLayout) LinearLayout root;
|
||||
|
||||
@BindView(R.id.install_option_card) CardView installOptionCard;
|
||||
@BindView(R.id.keep_force_enc) CheckBox keepEncChkbox;
|
||||
@BindView(R.id.keep_verity) CheckBox keepVerityChkbox;
|
||||
@BindView(R.id.install_option_expand) ViewGroup optionExpandLayout;
|
||||
@BindView(R.id.arrow) ImageView arrow;
|
||||
|
||||
@BindView(R.id.uninstall_button) CardView uninstallButton;
|
||||
|
||||
@BindColor(R.color.red500) int colorBad;
|
||||
@BindColor(R.color.green500) int colorOK;
|
||||
@BindColor(R.color.yellow500) int colorWarn;
|
||||
@BindColor(R.color.green500) int colorNeutral;
|
||||
@BindColor(R.color.blue500) int colorInfo;
|
||||
|
||||
private UpdateCardHolder magisk;
|
||||
private UpdateCardHolder manager;
|
||||
private SafetyNet safetyNet;
|
||||
private Transition transition;
|
||||
private Expandable optionExpand;
|
||||
|
||||
private void magiskInstall(View v) {
|
||||
// Show Manager update first
|
||||
if (Config.remoteManagerVersionCode > BuildConfig.VERSION_CODE) {
|
||||
new ManagerInstallDialog(requireActivity()).show();
|
||||
return;
|
||||
}
|
||||
new MagiskInstallDialog((BaseActivity) requireActivity()).show();
|
||||
}
|
||||
|
||||
private void managerInstall(View v) {
|
||||
new ManagerInstallDialog(requireActivity()).show();
|
||||
}
|
||||
|
||||
private void openLink(String url) {
|
||||
Utils.openLink(requireActivity(), Uri.parse(url));
|
||||
}
|
||||
|
||||
@OnClick(R.id.paypal)
|
||||
void paypal() {
|
||||
openLink(Const.Url.PAYPAL_URL);
|
||||
}
|
||||
|
||||
@OnClick(R.id.patreon)
|
||||
void patreon() {
|
||||
openLink(Const.Url.PATREON_URL);
|
||||
}
|
||||
|
||||
@OnClick(R.id.twitter)
|
||||
void twitter() {
|
||||
openLink(Const.Url.TWITTER_URL);
|
||||
}
|
||||
|
||||
@OnClick(R.id.github)
|
||||
void github() {
|
||||
openLink(Const.Url.SOURCE_CODE_URL);
|
||||
}
|
||||
|
||||
@OnClick(R.id.xda)
|
||||
void xda() {
|
||||
openLink(Const.Url.XDA_THREAD);
|
||||
}
|
||||
|
||||
@OnClick(R.id.uninstall_button)
|
||||
void uninstall() {
|
||||
new UninstallDialog(requireActivity()).show();
|
||||
}
|
||||
|
||||
@OnClick(R.id.arrow)
|
||||
void expandOptions() {
|
||||
if (optionExpand.isExpanded())
|
||||
optionExpand.collapse();
|
||||
else optionExpand.expand();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View v = inflater.inflate(R.layout.fragment_magisk, container, false);
|
||||
unbinder = new MagiskFragment_ViewBinding(this, v);
|
||||
requireActivity().setTitle(R.string.magisk);
|
||||
|
||||
optionExpand = new ArrowExpandable(new ExpandableViewHolder(optionExpandLayout), arrow);
|
||||
safetyNet = new SafetyNet(v);
|
||||
magisk = new UpdateCardHolder(inflater, root);
|
||||
manager = new UpdateCardHolder(inflater, root);
|
||||
manager.setClickable(vv ->
|
||||
MarkDownWindow.show(requireActivity(), null,
|
||||
getResources().openRawResource(R.raw.changelog)));
|
||||
root.addView(magisk.itemView, 1);
|
||||
root.addView(manager.itemView, 2);
|
||||
|
||||
keepVerityChkbox.setChecked(Config.keepVerity);
|
||||
keepVerityChkbox.setOnCheckedChangeListener((view, checked) -> Config.keepVerity = checked);
|
||||
keepEncChkbox.setChecked(Config.keepEnc);
|
||||
keepEncChkbox.setOnCheckedChangeListener((view, checked) -> Config.keepEnc = checked);
|
||||
|
||||
mSwipeRefreshLayout.setOnRefreshListener(this);
|
||||
|
||||
magisk.install.setOnClickListener(this::magiskInstall);
|
||||
manager.install.setOnClickListener(this::managerInstall);
|
||||
if (Config.get(Config.Key.COREONLY)) {
|
||||
magisk.additional.setText(R.string.core_only_enabled);
|
||||
magisk.additional.setVisibility(View.VISIBLE);
|
||||
}
|
||||
if (!app.getPackageName().equals(BuildConfig.APPLICATION_ID)) {
|
||||
manager.additional.setText("(" + app.getPackageName() + ")");
|
||||
manager.additional.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
transition = new TransitionSet()
|
||||
.setOrdering(TransitionSet.ORDERING_TOGETHER)
|
||||
.addTransition(new Fade(Fade.OUT))
|
||||
.addTransition(new ChangeBounds())
|
||||
.addTransition(new Fade(Fade.IN));
|
||||
|
||||
updateUI();
|
||||
return v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
safetyNet.unbinder.unbind();
|
||||
magisk.unbinder.unbind();
|
||||
manager.unbinder.unbind();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRefresh() {
|
||||
mSwipeRefreshLayout.setRefreshing(false);
|
||||
TransitionManager.beginDelayedTransition(root, transition);
|
||||
safetyNet.reset();
|
||||
magisk.reset();
|
||||
manager.reset();
|
||||
|
||||
Config.loadMagiskInfo();
|
||||
updateUI();
|
||||
|
||||
Event.reset(this);
|
||||
Config.remoteMagiskVersionString = null;
|
||||
Config.remoteMagiskVersionCode = -1;
|
||||
|
||||
shownDialog = false;
|
||||
|
||||
// Trigger state check
|
||||
if (Networking.checkNetworkStatus(app)) {
|
||||
CheckUpdates.check();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getListeningEvents() {
|
||||
return new int[] {Event.UPDATE_CHECK_DONE};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEvent(int event) {
|
||||
updateCheckUI();
|
||||
}
|
||||
|
||||
private void updateUI() {
|
||||
((MainActivity) requireActivity()).checkHideSection();
|
||||
int image, color;
|
||||
String status;
|
||||
if (Config.magiskVersionCode < 0) {
|
||||
color = colorBad;
|
||||
image = R.drawable.ic_cancel;
|
||||
status = getString(R.string.magisk_version_error);
|
||||
magisk.status.setText(status);
|
||||
magisk.currentVersion.setVisibility(View.GONE);
|
||||
} else {
|
||||
color = colorOK;
|
||||
image = R.drawable.ic_check_circle;
|
||||
status = getString(R.string.magisk);
|
||||
magisk.currentVersion.setText(getString(R.string.current_installed,
|
||||
String.format(Locale.US, "v%s (%d)",
|
||||
Config.magiskVersionString, Config.magiskVersionCode)));
|
||||
}
|
||||
magisk.statusIcon.setColorFilter(color);
|
||||
magisk.statusIcon.setImageResource(image);
|
||||
|
||||
manager.statusIcon.setColorFilter(colorOK);
|
||||
manager.statusIcon.setImageResource(R.drawable.ic_check_circle);
|
||||
manager.currentVersion.setText(getString(R.string.current_installed,
|
||||
String.format(Locale.US, "v%s (%d)",
|
||||
BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE)));
|
||||
|
||||
if (!Networking.checkNetworkStatus(app)) {
|
||||
// No network, updateCheckUI will not be triggered
|
||||
magisk.status.setText(status);
|
||||
manager.status.setText(R.string.app_name);
|
||||
magisk.setValid(false);
|
||||
manager.setValid(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateCheckUI() {
|
||||
int image, color;
|
||||
String status, button = "";
|
||||
|
||||
TransitionManager.beginDelayedTransition(root, transition);
|
||||
|
||||
if (Config.remoteMagiskVersionCode < 0) {
|
||||
color = colorNeutral;
|
||||
image = R.drawable.ic_help;
|
||||
status = getString(R.string.invalid_update_channel);
|
||||
} else {
|
||||
magisk.latestVersion.setText(getString(R.string.latest_version,
|
||||
String.format(Locale.US, "v%s (%d)",
|
||||
Config.remoteMagiskVersionString, Config.remoteMagiskVersionCode)));
|
||||
if (Config.remoteMagiskVersionCode > Config.magiskVersionCode) {
|
||||
color = colorInfo;
|
||||
image = R.drawable.ic_update;
|
||||
status = getString(R.string.magisk_update_title);
|
||||
button = getString(R.string.update);
|
||||
} else {
|
||||
color = colorOK;
|
||||
image = R.drawable.ic_check_circle;
|
||||
status = getString(R.string.magisk_up_to_date);
|
||||
button = getString(R.string.install);
|
||||
}
|
||||
}
|
||||
if (Config.magiskVersionCode > 0) {
|
||||
// Only override status if Magisk is installed
|
||||
magisk.statusIcon.setImageResource(image);
|
||||
magisk.statusIcon.setColorFilter(color);
|
||||
magisk.status.setText(status);
|
||||
magisk.install.setText(button);
|
||||
}
|
||||
|
||||
if (Config.remoteManagerVersionCode < 0) {
|
||||
color = colorNeutral;
|
||||
image = R.drawable.ic_help;
|
||||
status = getString(R.string.invalid_update_channel);
|
||||
} else {
|
||||
manager.latestVersion.setText(getString(R.string.latest_version,
|
||||
String.format(Locale.US, "v%s (%d)",
|
||||
Config.remoteManagerVersionString, Config.remoteManagerVersionCode)));
|
||||
if (Config.remoteManagerVersionCode > BuildConfig.VERSION_CODE) {
|
||||
color = colorInfo;
|
||||
image = R.drawable.ic_update;
|
||||
status = getString(R.string.manager_update_title);
|
||||
manager.install.setText(R.string.update);
|
||||
} else {
|
||||
color = colorOK;
|
||||
image = R.drawable.ic_check_circle;
|
||||
status = getString(R.string.manager_up_to_date);
|
||||
manager.install.setText(R.string.install);
|
||||
}
|
||||
}
|
||||
manager.statusIcon.setImageResource(image);
|
||||
manager.statusIcon.setColorFilter(color);
|
||||
manager.status.setText(status);
|
||||
|
||||
magisk.setValid(Config.remoteMagiskVersionCode > 0);
|
||||
manager.setValid(Config.remoteManagerVersionCode > 0);
|
||||
|
||||
if (Config.remoteMagiskVersionCode < 0) {
|
||||
// Hide install related components
|
||||
installOptionCard.setVisibility(View.GONE);
|
||||
uninstallButton.setVisibility(View.GONE);
|
||||
} else {
|
||||
// Show install related components
|
||||
installOptionCard.setVisibility(View.VISIBLE);
|
||||
uninstallButton.setVisibility(Shell.rootAccess() ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
if (!shownDialog && Config.magiskVersionCode > 0 &&
|
||||
!Shell.su("env_check").exec().isSuccess()) {
|
||||
shownDialog = true;
|
||||
new EnvFixDialog(requireActivity()).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
279
app/src/main/java/com/topjohnwu/magisk/ui/home/MagiskFragment.kt
Normal file
279
app/src/main/java/com/topjohnwu/magisk/ui/home/MagiskFragment.kt
Normal file
@ -0,0 +1,279 @@
|
||||
package com.topjohnwu.magisk.ui.home
|
||||
|
||||
import com.skoumal.teanity.viewevents.ViewEvent
|
||||
import com.topjohnwu.magisk.Config
|
||||
import com.topjohnwu.magisk.R
|
||||
import com.topjohnwu.magisk.model.events.MagiskInstallEvent
|
||||
import com.topjohnwu.magisk.model.events.ManagerInstallEvent
|
||||
import com.topjohnwu.magisk.model.events.OpenLinkEvent
|
||||
import com.topjohnwu.magisk.model.events.UninstallEvent
|
||||
import com.topjohnwu.magisk.utils.Event
|
||||
import com.topjohnwu.magisk.view.MarkDownWindow
|
||||
import com.topjohnwu.magisk.view.dialogs.ManagerInstallDialog
|
||||
import com.topjohnwu.magisk.view.dialogs.UninstallDialog
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
import com.topjohnwu.magisk.ui.base.MagiskFragment as NewMagiskFragment
|
||||
|
||||
class MagiskFragment : NewMagiskFragment<HomeViewModel, com.topjohnwu.magisk.databinding.FragmentMagiskBinding>() {
|
||||
|
||||
/*@BindView(R.id.swipeRefreshLayout)
|
||||
internal var mSwipeRefreshLayout: SwipeRefreshLayout? = null
|
||||
@BindView(R.id.linearLayout)
|
||||
internal var root: LinearLayout? = null
|
||||
|
||||
@BindView(R.id.install_option_card)
|
||||
internal var installOptionCard: CardView? = null
|
||||
@BindView(R.id.keep_force_enc)
|
||||
internal var keepEncChkbox: CheckBox? = null
|
||||
@BindView(R.id.keep_verity)
|
||||
internal var keepVerityChkbox: CheckBox? = null
|
||||
@BindView(R.id.install_option_expand)
|
||||
internal var optionExpandLayout: ViewGroup? = null
|
||||
@BindView(R.id.arrow)
|
||||
internal var arrow: ImageView? = null
|
||||
|
||||
@BindView(R.id.uninstall_button)
|
||||
internal var uninstallButton: CardView? = null
|
||||
|
||||
@BindColor(R.color.red500)
|
||||
internal var colorBad: Int = 0
|
||||
@BindColor(R.color.green500)
|
||||
internal var colorOK: Int = 0
|
||||
@BindColor(R.color.yellow500)
|
||||
internal var colorWarn: Int = 0
|
||||
@BindColor(R.color.green500)
|
||||
internal var colorNeutral: Int = 0
|
||||
@BindColor(R.color.blue500)
|
||||
internal var colorInfo: Int = 0*/
|
||||
|
||||
/*private var magisk: UpdateCardHolder? = null
|
||||
private var manager: UpdateCardHolder? = null
|
||||
private var safetyNet: SafetyNet? = null
|
||||
private var transition: Transition? = null
|
||||
private var optionExpand: Expandable? = null*/
|
||||
|
||||
override val layoutRes: Int = R.layout.fragment_magisk
|
||||
override val viewModel: HomeViewModel by viewModel()
|
||||
|
||||
override fun onEventDispatched(event: ViewEvent) {
|
||||
super.onEventDispatched(event)
|
||||
when (event) {
|
||||
is OpenLinkEvent -> openLink(event.url)
|
||||
is ManagerInstallEvent -> installManager()
|
||||
is MagiskInstallEvent -> installMagisk()
|
||||
is UninstallEvent -> uninstall()
|
||||
}
|
||||
}
|
||||
|
||||
private fun installMagisk() {
|
||||
// Show Manager update first
|
||||
if (Config.remoteManagerVersionCode > BuildConfig.VERSION_CODE) {
|
||||
ManagerInstallDialog(requireActivity()).show()
|
||||
return
|
||||
}
|
||||
//FIXME dialog requires old base
|
||||
//MagiskInstallDialog(requireActivity()).show()
|
||||
}
|
||||
|
||||
private fun installManager() = ManagerInstallDialog(requireActivity()).show()
|
||||
|
||||
private fun uninstall() {
|
||||
UninstallDialog(requireActivity()).show()
|
||||
}
|
||||
|
||||
private fun changelogManager() {
|
||||
MarkDownWindow.show(
|
||||
requireActivity(), null,
|
||||
resources.openRawResource(R.raw.changelog)
|
||||
)
|
||||
}
|
||||
|
||||
/*override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
val v = inflater.inflate(R.layout.fragment_magisk, container, false)
|
||||
requireActivity().setTitle(R.string.magisk)
|
||||
|
||||
//safetyNet = SafetyNet(v)
|
||||
|
||||
*//*transition = TransitionSet()
|
||||
.setOrdering(TransitionSet.ORDERING_TOGETHER)
|
||||
.addTransition(Fade(Fade.OUT))
|
||||
.addTransition(ChangeBounds())
|
||||
.addTransition(Fade(Fade.IN))*//*
|
||||
|
||||
updateUI()
|
||||
return v
|
||||
}*/
|
||||
|
||||
private fun onRefresh() {
|
||||
/*mSwipeRefreshLayout!!.isRefreshing = false
|
||||
TransitionManager.beginDelayedTransition(root!!, transition)
|
||||
safetyNet!!.reset()
|
||||
magisk!!.reset()
|
||||
manager!!.reset()*/
|
||||
|
||||
Config.loadMagiskInfo()
|
||||
updateUI()
|
||||
|
||||
//FIXME requires old base
|
||||
/*Event.reset(this)
|
||||
Config.remoteMagiskVersionString = null
|
||||
Config.remoteMagiskVersionCode = -1*/
|
||||
|
||||
shownDialog = false
|
||||
|
||||
// Trigger state check
|
||||
/*if (Networking.checkNetworkStatus(app)) {
|
||||
CheckUpdates.check()
|
||||
}*/
|
||||
}
|
||||
|
||||
private fun getListeningEvents(): IntArray {
|
||||
return intArrayOf(Event.UPDATE_CHECK_DONE)
|
||||
}
|
||||
|
||||
private fun onEvent(event: Int) {
|
||||
updateCheckUI()
|
||||
}
|
||||
|
||||
private fun updateUI() {
|
||||
/*(requireActivity() as MainActivity).checkHideSection()
|
||||
val image: Int
|
||||
val color: Int
|
||||
val status: String
|
||||
if (Config.magiskVersionCode < 0) {
|
||||
color = colorBad
|
||||
image = R.drawable.ic_cancel
|
||||
status = getString(R.string.magisk_version_error)
|
||||
magisk!!.status.text = status
|
||||
magisk!!.currentVersion.visibility = View.GONE
|
||||
} else {
|
||||
color = colorOK
|
||||
image = R.drawable.ic_check_circle
|
||||
status = getString(R.string.magisk)
|
||||
magisk!!.currentVersion.text = getString(
|
||||
R.string.current_installed,
|
||||
String.format(
|
||||
Locale.US, "v%s (%d)",
|
||||
Config.magiskVersionString, Config.magiskVersionCode
|
||||
)
|
||||
)
|
||||
}
|
||||
magisk!!.statusIcon.setColorFilter(color)
|
||||
magisk!!.statusIcon.setImageResource(image)
|
||||
|
||||
manager!!.statusIcon.setColorFilter(colorOK)
|
||||
manager!!.statusIcon.setImageResource(R.drawable.ic_check_circle)
|
||||
manager!!.currentVersion.text = getString(
|
||||
R.string.current_installed,
|
||||
String.format(
|
||||
Locale.US, "v%s (%d)",
|
||||
BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE
|
||||
)
|
||||
)
|
||||
|
||||
if (!Networking.checkNetworkStatus(app)) {
|
||||
// No network, updateCheckUI will not be triggered
|
||||
magisk!!.status.text = status
|
||||
manager!!.status.setText(R.string.app_name)
|
||||
magisk!!.setValid(false)
|
||||
manager!!.setValid(false)
|
||||
}*/
|
||||
}
|
||||
|
||||
private fun updateCheckUI() {
|
||||
/*var image: Int
|
||||
var color: Int
|
||||
var status: String
|
||||
var button = ""
|
||||
|
||||
|
||||
if (Config.remoteMagiskVersionCode < 0) {
|
||||
color = colorNeutral
|
||||
image = R.drawable.ic_help
|
||||
status = getString(R.string.invalid_update_channel)
|
||||
} else {
|
||||
magisk!!.latestVersion.text = getString(
|
||||
R.string.latest_version,
|
||||
String.format(
|
||||
Locale.US, "v%s (%d)",
|
||||
Config.remoteMagiskVersionString, Config.remoteMagiskVersionCode
|
||||
)
|
||||
)
|
||||
if (Config.remoteMagiskVersionCode > Config.magiskVersionCode) {
|
||||
color = colorInfo
|
||||
image = R.drawable.ic_update
|
||||
status = getString(R.string.magisk_update_title)
|
||||
button = getString(R.string.update)
|
||||
} else {
|
||||
color = colorOK
|
||||
image = R.drawable.ic_check_circle
|
||||
status = getString(R.string.magisk_up_to_date)
|
||||
button = getString(R.string.install)
|
||||
}
|
||||
}
|
||||
if (Config.magiskVersionCode > 0) {
|
||||
// Only override status if Magisk is installed
|
||||
magisk!!.statusIcon.setImageResource(image)
|
||||
magisk!!.statusIcon.setColorFilter(color)
|
||||
magisk!!.status.text = status
|
||||
magisk!!.install.text = button
|
||||
}
|
||||
|
||||
if (Config.remoteManagerVersionCode < 0) {
|
||||
color = colorNeutral
|
||||
image = R.drawable.ic_help
|
||||
status = getString(R.string.invalid_update_channel)
|
||||
} else {
|
||||
manager!!.latestVersion.text = getString(
|
||||
R.string.latest_version,
|
||||
String.format(
|
||||
Locale.US, "v%s (%d)",
|
||||
Config.remoteManagerVersionString, Config.remoteManagerVersionCode
|
||||
)
|
||||
)
|
||||
if (Config.remoteManagerVersionCode > BuildConfig.VERSION_CODE) {
|
||||
color = colorInfo
|
||||
image = R.drawable.ic_update
|
||||
status = getString(R.string.manager_update_title)
|
||||
manager!!.install.setText(R.string.update)
|
||||
} else {
|
||||
color = colorOK
|
||||
image = R.drawable.ic_check_circle
|
||||
status = getString(R.string.manager_up_to_date)
|
||||
manager!!.install.setText(R.string.install)
|
||||
}
|
||||
}
|
||||
manager!!.statusIcon.setImageResource(image)
|
||||
manager!!.statusIcon.setColorFilter(color)
|
||||
manager!!.status.text = status
|
||||
|
||||
magisk!!.setValid(Config.remoteMagiskVersionCode > 0)
|
||||
manager!!.setValid(Config.remoteManagerVersionCode > 0)
|
||||
|
||||
if (Config.remoteMagiskVersionCode < 0) {
|
||||
// Hide install related components
|
||||
installOptionCard!!.visibility = View.GONE
|
||||
uninstallButton!!.visibility = View.GONE
|
||||
} else {
|
||||
// Show install related components
|
||||
installOptionCard!!.visibility = View.VISIBLE
|
||||
uninstallButton!!.visibility = if (Shell.rootAccess()) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
if (!shownDialog && Config.magiskVersionCode > 0 &&
|
||||
!Shell.su("env_check").exec().isSuccess
|
||||
) {
|
||||
shownDialog = true
|
||||
EnvFixDialog(requireActivity()).show()
|
||||
}*/
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private var shownDialog = false
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,6 @@
|
||||
package com.topjohnwu.magisk.ui.home
|
||||
|
||||
|
||||
enum class MagiskItem {
|
||||
MANAGER, MAGISK
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
package com.topjohnwu.magisk.ui.home
|
||||
|
||||
|
||||
enum class MagiskState {
|
||||
NO_ROOT, NOT_INSTALLED, UP_TO_DATE, OBSOLETE, LOADING
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
package com.topjohnwu.magisk.utils
|
||||
|
||||
import android.view.View
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.appcompat.widget.AppCompatImageView
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.databinding.BindingAdapter
|
||||
|
||||
@ -9,3 +11,8 @@ import androidx.databinding.BindingAdapter
|
||||
fun setOnNavigationClickedListener(view: Toolbar, listener: View.OnClickListener) {
|
||||
view.setNavigationOnClickListener(listener)
|
||||
}
|
||||
|
||||
@BindingAdapter("srcCompat")
|
||||
fun setImageResource(view: AppCompatImageView, @DrawableRes resId: Int) {
|
||||
view.setImageResource(resId)
|
||||
}
|
||||
|
8
app/src/main/java/com/topjohnwu/magisk/utils/XBinding.kt
Normal file
8
app/src/main/java/com/topjohnwu/magisk/utils/XBinding.kt
Normal file
@ -0,0 +1,8 @@
|
||||
package com.topjohnwu.magisk.utils
|
||||
|
||||
import com.skoumal.teanity.util.KObservableField
|
||||
|
||||
|
||||
fun KObservableField<Boolean>.toggle() {
|
||||
value = !value
|
||||
}
|
@ -1,10 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<data>
|
||||
|
||||
<import type="com.topjohnwu.magisk.ui.home.MagiskState" />
|
||||
|
||||
<import type="com.topjohnwu.magisk.ui.home.MagiskItem" />
|
||||
|
||||
<variable
|
||||
name="viewModel"
|
||||
type="com.topjohnwu.magisk.ui.home.HomeViewModel" />
|
||||
|
||||
</data>
|
||||
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
android:id="@+id/swipeRefreshLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:orientation="vertical">
|
||||
android:orientation="vertical"
|
||||
app:onRefreshListener="@{() -> viewModel.refresh()}"
|
||||
app:refreshing="@{viewModel.loading}">
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
@ -68,6 +84,26 @@
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<include
|
||||
android:id="@+id/home_magisk_version"
|
||||
additionalInfo="@{viewModel.magiskAdditionalInfo}"
|
||||
currentVersion="@{viewModel.magiskCurrentVersion}"
|
||||
item="@{MagiskItem.MAGISK}"
|
||||
latestVersion="@{viewModel.magiskLatestVersion}"
|
||||
layout="@layout/include_update_card"
|
||||
state="@{viewModel.magiskState}"
|
||||
text="@{viewModel.magiskStateText}" />
|
||||
|
||||
<include
|
||||
android:id="@+id/home_manager_version"
|
||||
additionalInfo="@{viewModel.managerAdditionalInfo}"
|
||||
currentVersion="@{viewModel.managerCurrentVersion}"
|
||||
item="@{MagiskItem.MANAGER}"
|
||||
latestVersion="@{viewModel.managerLatestVersion}"
|
||||
layout="@layout/include_update_card"
|
||||
state="@{viewModel.managerState}"
|
||||
text="@{viewModel.managerStateText}" />
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/install_option_card"
|
||||
style="?attr/cardStyle"
|
||||
@ -78,13 +114,13 @@
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:visibility="gone"
|
||||
app:cardCornerRadius="@dimen/card_corner_radius"
|
||||
app:cardElevation="@dimen/card_elevation">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:onClick="@{() -> viewModel.advancedPressed()}"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingBottom="10dp">
|
||||
@ -93,6 +129,18 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/arrow"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:rotation="@{viewModel.isAdvancedExpanded ? 180 : 0}"
|
||||
android:tint="?attr/imageColorTint"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/title"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@drawable/ic_arrow" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
@ -105,21 +153,11 @@
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/arrow"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:tint="?attr/imageColorTint"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/title"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@drawable/ic_arrow" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/install_option_expand"
|
||||
gone="@{!viewModel.isAdvancedExpanded}"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
@ -130,6 +168,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="50dp"
|
||||
android:layout_marginEnd="50dp"
|
||||
android:checked="@={viewModel.isForceEncryption}"
|
||||
android:text="@string/keep_force_encryption" />
|
||||
|
||||
<CheckBox
|
||||
@ -138,6 +177,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="50dp"
|
||||
android:layout_marginEnd="50dp"
|
||||
android:checked="@={viewModel.isKeepVerity}"
|
||||
android:text="@string/keep_dm_verity" />
|
||||
|
||||
</LinearLayout>
|
||||
@ -180,36 +220,6 @@
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@drawable/ic_safetynet" />
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/sn_status_start"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintGuide_percent="0.25" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/safetyNet_status"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:maxLines="1"
|
||||
android:minWidth="200dp"
|
||||
android:text="@string/safetyNet_check_text"
|
||||
android:textStyle="bold"
|
||||
app:autoSizeMaxTextSize="14sp"
|
||||
app:autoSizeTextType="uniform"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/sn_status_end"
|
||||
app:layout_constraintStart_toStartOf="@+id/sn_status_start"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/sn_status_end"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintGuide_percent="0.75" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/safetyNet_refresh"
|
||||
android:layout_width="25dp"
|
||||
@ -230,6 +240,36 @@
|
||||
app:layout_constraintStart_toStartOf="@+id/safetyNet_refresh"
|
||||
app:layout_constraintTop_toTopOf="@+id/safetyNet_refresh" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/safetyNet_status"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:maxLines="1"
|
||||
android:minWidth="200dp"
|
||||
android:text="@string/safetyNet_check_text"
|
||||
android:textStyle="bold"
|
||||
app:autoSizeMaxTextSize="14sp"
|
||||
app:autoSizeTextType="uniform"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/sn_status_end"
|
||||
app:layout_constraintStart_toStartOf="@+id/sn_status_start"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/sn_status_start"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintGuide_percent="0.25" />
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/sn_status_end"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintGuide_percent="0.75" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
@ -247,16 +287,6 @@
|
||||
app:layout_constraintEnd_toStartOf="@+id/cts_status"
|
||||
app:layout_constraintTop_toTopOf="@+id/cts_status" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/cts_status"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="6dp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintEnd_toEndOf="@+id/basic_status"
|
||||
app:layout_constraintStart_toStartOf="@+id/basic_status"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/basic_status_icon"
|
||||
android:layout_width="25dp"
|
||||
@ -269,6 +299,16 @@
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/basic_status" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/cts_status"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="6dp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintEnd_toEndOf="@+id/basic_status"
|
||||
app:layout_constraintStart_toStartOf="@+id/basic_status"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/basic_status"
|
||||
android:layout_width="wrap_content"
|
||||
@ -304,36 +344,72 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/paypal"
|
||||
<FrameLayout
|
||||
android:id="@+id/twitter"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintEnd_toStartOf="@+id/patreon"
|
||||
android:foreground="?android:attr/selectableItemBackground"
|
||||
android:onClick="@{() -> viewModel.twitterPressed()}"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/github"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
app:layout_constraintTop_toBottomOf="@+id/paypal">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="35dp"
|
||||
android:layout_height="35dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_margin="10dp"
|
||||
android:tint="?attr/imageColorTint"
|
||||
app:srcCompat="@drawable/ic_paypal" />
|
||||
app:srcCompat="@drawable/ic_twitter" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/github"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_margin="5dp"
|
||||
android:text="PayPal"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:foreground="?android:attr/selectableItemBackground"
|
||||
android:onClick="@{() -> viewModel.githubPressed()}"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/xda"
|
||||
app:layout_constraintStart_toEndOf="@+id/twitter">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="35dp"
|
||||
android:layout_height="35dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_margin="10dp"
|
||||
android:tint="?attr/imageColorTint"
|
||||
app:srcCompat="@drawable/ic_github" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/xda"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:foreground="?android:attr/selectableItemBackground"
|
||||
android:onClick="@{() -> viewModel.xdaPressed()}"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/github">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="35dp"
|
||||
android:layout_height="35dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_margin="10dp"
|
||||
android:tint="?attr/imageColorTint"
|
||||
app:srcCompat="@drawable/ic_xda" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/patreon"
|
||||
@ -343,6 +419,7 @@
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:gravity="center_horizontal"
|
||||
android:onClick="@{() -> viewModel.patreonPressed()}"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/paypal"
|
||||
@ -366,69 +443,37 @@
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/twitter"
|
||||
<LinearLayout
|
||||
android:id="@+id/paypal"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:foreground="?android:attr/selectableItemBackground"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/github"
|
||||
android:gravity="center_horizontal"
|
||||
android:onClick="@{() -> viewModel.paypalPressed()}"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintEnd_toStartOf="@+id/patreon"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/paypal">
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="35dp"
|
||||
android:layout_height="35dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_gravity="center"
|
||||
android:layout_margin="10dp"
|
||||
android:tint="?attr/imageColorTint"
|
||||
app:srcCompat="@drawable/ic_twitter" />
|
||||
app:srcCompat="@drawable/ic_paypal" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/github"
|
||||
android:layout_width="0dp"
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:foreground="?android:attr/selectableItemBackground"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/xda"
|
||||
app:layout_constraintStart_toEndOf="@+id/twitter">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="35dp"
|
||||
android:layout_height="35dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_margin="10dp"
|
||||
android:tint="?attr/imageColorTint"
|
||||
app:srcCompat="@drawable/ic_github" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/xda"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:foreground="?android:attr/selectableItemBackground"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/github">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="35dp"
|
||||
android:layout_height="35dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_margin="10dp"
|
||||
android:tint="?attr/imageColorTint"
|
||||
app:srcCompat="@drawable/ic_xda" />
|
||||
|
||||
</FrameLayout>
|
||||
android:layout_gravity="center"
|
||||
android:layout_margin="5dp"
|
||||
android:text="PayPal"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
@ -447,6 +492,7 @@
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:foreground="?android:attr/selectableItemBackground"
|
||||
android:onClick="@{() -> viewModel.uninstallPressed()}"
|
||||
app:cardCornerRadius="@dimen/card_corner_radius"
|
||||
app:cardElevation="@dimen/card_elevation">
|
||||
|
||||
@ -470,3 +516,5 @@
|
||||
</ScrollView>
|
||||
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||
|
||||
</layout>
|
||||
|
160
app/src/main/res/layout/include_update_card.xml
Normal file
160
app/src/main/res/layout/include_update_card.xml
Normal file
@ -0,0 +1,160 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<data>
|
||||
|
||||
<import type="com.topjohnwu.magisk.ui.home.MagiskState" />
|
||||
|
||||
<import type="com.topjohnwu.magisk.R" />
|
||||
|
||||
<variable
|
||||
name="item"
|
||||
type="com.topjohnwu.magisk.ui.home.MagiskItem" />
|
||||
|
||||
<variable
|
||||
name="state"
|
||||
type="com.topjohnwu.magisk.ui.home.MagiskState" />
|
||||
|
||||
<variable
|
||||
name="text"
|
||||
type="String" />
|
||||
|
||||
<variable
|
||||
name="currentVersion"
|
||||
type="String" />
|
||||
|
||||
<variable
|
||||
name="latestVersion"
|
||||
type="String" />
|
||||
|
||||
<variable
|
||||
name="additionalInfo"
|
||||
type="String" />
|
||||
|
||||
<variable
|
||||
name="viewModel"
|
||||
type="com.topjohnwu.magisk.ui.home.HomeViewModel" />
|
||||
|
||||
</data>
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
style="?attr/cardStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:foreground="?android:attr/selectableItemBackground"
|
||||
android:onClick="@{() -> viewModel.cardPressed(item)}"
|
||||
app:cardCornerRadius="@dimen/card_corner_radius"
|
||||
app:cardElevation="@dimen/card_elevation">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingTop="12dp"
|
||||
android:paddingBottom="12dp">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatButton
|
||||
android:id="@+id/install"
|
||||
gone="@{state == MagiskState.LOADING}"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:onClick="@{() -> viewModel.installPressed(item)}"
|
||||
android:text="@{state != MagiskState.OBSOLETE ? @string/install : @string/update}"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="@string/install" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/status_icon"
|
||||
invisible="@{state == MagiskState.LOADING}"
|
||||
srcCompat="@{state == MagiskState.UP_TO_DATE ? R.drawable.ic_check_circle : (state == MagiskState.OBSOLETE ? R.drawable.ic_update : R.drawable.ic_help)}"
|
||||
android:layout_width="25dp"
|
||||
android:layout_height="25dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/status"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progress"
|
||||
gone="state != MagiskState.LOADING"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/status_icon"
|
||||
app:layout_constraintEnd_toEndOf="@+id/status_icon"
|
||||
app:layout_constraintStart_toStartOf="@+id/status_icon"
|
||||
app:layout_constraintTop_toTopOf="@+id/status_icon" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/current_version"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxLines="1"
|
||||
android:text="@{state != MagiskState.LOADING ? currentVersion : @string/checking_for_updates}"
|
||||
app:autoSizeMinTextSize="1sp"
|
||||
app:autoSizeTextType="uniform"
|
||||
app:layout_constraintEnd_toEndOf="@+id/status"
|
||||
app:layout_constraintStart_toStartOf="@+id/status"
|
||||
app:layout_constraintTop_toBottomOf="@+id/status"
|
||||
tools:text="@string/checking_for_updates" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/latest_version"
|
||||
gone="@{currentVersion == latestVersion}"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxLines="1"
|
||||
android:text="@{state != MagiskState.LOADING ? latestVersion : @string/checking_for_updates}"
|
||||
app:autoSizeMinTextSize="1sp"
|
||||
app:autoSizeTextType="uniform"
|
||||
app:layout_constraintEnd_toEndOf="@+id/status"
|
||||
app:layout_constraintStart_toStartOf="@+id/status"
|
||||
app:layout_constraintTop_toBottomOf="@+id/current_version"
|
||||
tools:text="@string/checking_for_updates" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/additional"
|
||||
gone="@{additionalInfo.length == 0}"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxLines="1"
|
||||
android:text="@{additionalInfo}"
|
||||
app:autoSizeMinTextSize="1sp"
|
||||
app:autoSizeTextType="uniform"
|
||||
app:layout_constraintEnd_toEndOf="@+id/status"
|
||||
app:layout_constraintStart_toStartOf="@+id/status"
|
||||
app:layout_constraintTop_toBottomOf="@+id/latest_version"
|
||||
tools:text="@string/checking_for_updates" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/status"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:maxLines="1"
|
||||
android:paddingTop="3dp"
|
||||
android:paddingBottom="3dp"
|
||||
android:text="@{text}"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
app:autoSizeMinTextSize="1sp"
|
||||
app:autoSizeTextType="uniform"
|
||||
app:layout_constraintEnd_toStartOf="@+id/install"
|
||||
app:layout_constraintStart_toEndOf="@+id/status_icon"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="Magisk is up to date" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
|
||||
</layout>
|
@ -75,7 +75,6 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:maxLines="1"
|
||||
android:text="@string/checking_for_updates"
|
||||
android:visibility="gone"
|
||||
app:autoSizeMinTextSize="1sp"
|
||||
app:autoSizeTextType="uniform"
|
||||
app:layout_constraintEnd_toEndOf="@+id/status"
|
||||
@ -87,7 +86,6 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxLines="1"
|
||||
android:visibility="gone"
|
||||
app:autoSizeMinTextSize="1sp"
|
||||
app:autoSizeTextType="uniform"
|
||||
app:layout_constraintEnd_toEndOf="@+id/status"
|
||||
@ -101,7 +99,6 @@
|
||||
android:layout_marginEnd="8dp"
|
||||
android:maxLines="1"
|
||||
android:text="@string/install"
|
||||
android:visibility="gone"
|
||||
app:autoSizeMaxTextSize="14sp"
|
||||
app:autoSizeTextType="uniform"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
|
Loading…
Reference in New Issue
Block a user