X-Git-Url: https://git.ktnx.net/?p=mobile-ledger.git;a=blobdiff_plain;f=app%2Fsrc%2Fmain%2Fjava%2Fnet%2Fktnx%2Fmobileledger%2Fui%2Fprofiles%2FProfileDetailFragment.java;h=c6dbc6a587c1799244b6656de63d95c4bba9cf5f;hp=4f61ba2e1d305f714c56737357335628eab709c3;hb=a4295cb43de54dd0428563d46e66a89320f6afef;hpb=bd5da50ef980c0c9657ec1e9c3e681ab5092f438 diff --git a/app/src/main/java/net/ktnx/mobileledger/ui/profiles/ProfileDetailFragment.java b/app/src/main/java/net/ktnx/mobileledger/ui/profiles/ProfileDetailFragment.java index 4f61ba2e..c6dbc6a5 100644 --- a/app/src/main/java/net/ktnx/mobileledger/ui/profiles/ProfileDetailFragment.java +++ b/app/src/main/java/net/ktnx/mobileledger/ui/profiles/ProfileDetailFragment.java @@ -19,7 +19,6 @@ package net.ktnx.mobileledger.ui.profiles; import android.app.Activity; import android.app.AlertDialog; -import android.content.DialogInterface; import android.os.Bundle; import android.text.Editable; import android.text.TextWatcher; @@ -45,11 +44,17 @@ import net.ktnx.mobileledger.ui.HueRingDialog; import net.ktnx.mobileledger.ui.activity.ProfileDetailActivity; import net.ktnx.mobileledger.utils.Colors; +import org.jetbrains.annotations.NotNull; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.ArrayList; import java.util.Objects; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; import static net.ktnx.mobileledger.utils.Logger.debug; @@ -91,7 +96,7 @@ public class ProfileDetailFragment extends Fragment implements HueRingDialog.Hue public ProfileDetailFragment() { } @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + public void onCreateOptionsMenu(@NotNull Menu menu, @NotNull MenuInflater inflater) { debug("profiles", "[fragment] Creating profile details options menu"); super.onCreateOptionsMenu(menu, inflater); inflater.inflate(R.menu.profile_details, menu); @@ -100,44 +105,64 @@ public class ProfileDetailFragment extends Fragment implements HueRingDialog.Hue AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); builder.setTitle(mProfile.getName()); builder.setMessage(R.string.remove_profile_dialog_message); - builder.setPositiveButton(R.string.Remove, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - debug("profiles", - String.format("[fragment] removing profile %s", mProfile.getUuid())); - mProfile.removeFromDB(); - Data.profiles.remove(mProfile); - if (Data.profile.get().equals(mProfile)) { - debug("profiles", "[fragment] setting current profile to 0"); - Data.setCurrentProfile(Data.profiles.get(0)); - } - getActivity().finish(); + builder.setPositiveButton(R.string.Remove, (dialog, which) -> { + debug("profiles", + String.format("[fragment] removing profile %s", mProfile.getUuid())); + mProfile.removeFromDB(); + ArrayList oldList = Data.profiles.getValue(); + if (oldList == null) throw new AssertionError(); + ArrayList newList = + (ArrayList) oldList.clone(); + newList.remove(mProfile); + Data.profiles.setValue(newList); + if (mProfile.equals(Data.profile.getValue())) { + debug("profiles", "[fragment] setting current profile to 0"); + Data.setCurrentProfile(newList.get(0)); } + + final FragmentActivity activity = getActivity(); + if (activity != null) activity.finish(); }); builder.show(); return false; }); - menuDeleteProfile.setVisible((mProfile != null) && (Data.profiles.size() > 1)); + final ArrayList profiles = Data.profiles.getValue(); + menuDeleteProfile + .setVisible((mProfile != null) && (profiles != null) && (profiles.size() > 1)); if (BuildConfig.DEBUG) { final MenuItem menuWipeProfileData = menu.findItem(R.id.menuWipeData); - menuWipeProfileData.setOnMenuItemClickListener(this::onWipeDataMenuClicked); + menuWipeProfileData.setOnMenuItemClickListener(ignored -> onWipeDataMenuClicked()); menuWipeProfileData.setVisible(mProfile != null); } } - private boolean onWipeDataMenuClicked(MenuItem item) { + private boolean onWipeDataMenuClicked() { // this is a development option, so no confirmation mProfile.wipeAllData(); - Data.profile.forceNotifyObservers(); + if (mProfile.equals(Data.profile.getValue())) triggerProfileChange(); return true; } + private void triggerProfileChange() { + int index = Data.getProfileIndex(mProfile); + MobileLedgerProfile newProfile = new MobileLedgerProfile(mProfile); + final ArrayList profiles = Data.profiles.getValue(); + if (profiles == null) throw new AssertionError(); + profiles.set(index, newProfile); + + ProfilesRecyclerViewAdapter prva = ProfilesRecyclerViewAdapter.getInstance(); + if (prva != null) prva.notifyItemChanged(index); + + if (mProfile.equals(Data.profile.getValue())) Data.profile.setValue(newProfile); + } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if ((getArguments() != null) && getArguments().containsKey(ARG_ITEM_ID)) { int index = getArguments().getInt(ARG_ITEM_ID, -1); - if (index != -1) mProfile = Data.profiles.get(index); + ArrayList profiles = Data.profiles.getValue(); + if ((profiles != null) && (index != -1) && (index < profiles.size())) + mProfile = profiles.get(index); Activity activity = this.getActivity(); if (activity == null) throw new AssertionError(); @@ -155,38 +180,38 @@ public class ProfileDetailFragment extends Fragment implements HueRingDialog.Hue if (context == null) return; FloatingActionButton fab = context.findViewById(R.id.fab); - fab.setOnClickListener(v -> { - if (!checkValidity()) return; - - if (mProfile != null) { - updateProfileFromUI(); -// debug("profiles", String.format("Selected item is %d", mProfile.getThemeId())); - mProfile.storeInDB(); - debug("profiles", "profile stored in DB"); - Data.profiles.triggerItemChangedNotification(mProfile); + fab.setOnClickListener(v -> onSaveFabClicked()); + profileName.requestFocus(); + } + private void onSaveFabClicked() { + if (!checkValidity()) return; - if (mProfile.getUuid().equals(Data.profile.get().getUuid())) { - // dummy update to notify the observers of the possibly new name/URL - Data.profile.forceNotifyObservers(); - } - } - else { - mProfile = new MobileLedgerProfile(); - updateProfileFromUI(); - mProfile.storeInDB(); - Data.profiles.add(mProfile); - MobileLedgerProfile.storeProfilesOrder(); - - // first profile ever? - if (Data.profiles.size() == 1) Data.profile.set(mProfile); - } + if (mProfile != null) { + updateProfileFromUI(); +// debug("profiles", String.format("Selected item is %d", mProfile.getThemeId())); + mProfile.storeInDB(); + debug("profiles", "profile stored in DB"); + triggerProfileChange(); + } + else { + mProfile = new MobileLedgerProfile(); + updateProfileFromUI(); + mProfile.storeInDB(); + final ArrayList profiles = Data.profiles.getValue(); + if (profiles == null) throw new AssertionError(); + ArrayList newList = + (ArrayList) profiles.clone(); + newList.add(mProfile); + Data.profiles.setValue(newList); + MobileLedgerProfile.storeProfilesOrder(); - Activity activity = getActivity(); - if (activity != null) activity.finish(); - }); + // first profile ever? + if (newList.size() == 1) Data.profile.setValue(mProfile); + } - profileName.requestFocus(); + Activity activity = getActivity(); + if (activity != null) activity.finish(); } private void updateProfileFromUI() { mProfile.setName(profileName.getText()); @@ -225,9 +250,9 @@ public class ProfileDetailFragment extends Fragment implements HueRingDialog.Hue if (isChecked) userName.requestFocus(); }); - postingPermitted.setOnCheckedChangeListener(((buttonView, isChecked) -> { - preferredAccountsFilterLayout.setVisibility(isChecked ? View.VISIBLE : View.GONE); - })); + postingPermitted.setOnCheckedChangeListener( + ((buttonView, isChecked) -> preferredAccountsFilterLayout + .setVisibility(isChecked ? View.VISIBLE : View.GONE))); hookClearErrorOnFocusListener(profileName, profileNameLayout); hookClearErrorOnFocusListener(url, urlLayout); @@ -265,8 +290,8 @@ public class ProfileDetailFragment extends Fragment implements HueRingDialog.Hue huePickerView.setTag(profileThemeId); huePickerView.setOnClickListener(v -> { HueRingDialog d = new HueRingDialog( - Objects.requireNonNull(ProfileDetailFragment.this.getContext()), - profileThemeId, (Integer) v.getTag()); + Objects.requireNonNull(ProfileDetailFragment.this.getContext()), profileThemeId, + (Integer) v.getTag()); d.show(); d.setColorSelectedListener(this); }); @@ -298,11 +323,20 @@ public class ProfileDetailFragment extends Fragment implements HueRingDialog.Hue profileNameLayout.setError(getResources().getText(R.string.err_profile_name_empty)); } - val = String.valueOf(url.getText()); - if (val.trim().isEmpty()) { + val = String.valueOf(url.getText()).trim(); + if (val.isEmpty()) { valid = false; urlLayout.setError(getResources().getText(R.string.err_profile_url_empty)); } + try { + URL url = new URL(val); + String host = url.getHost(); + if (host == null || host.isEmpty()) throw new MalformedURLException("Missing host"); + } + catch (MalformedURLException e) { + valid = false; + urlLayout.setError(getResources().getText(R.string.err_invalid_url)); + } if (useAuthentication.isChecked()) { val = String.valueOf(userName.getText()); if (val.trim().isEmpty()) {