From 6f35b0778f75ecd3d87fd9777ff475d672cba63c Mon Sep 17 00:00:00 2001 From: M66B Date: Thu, 9 Jul 2026 07:35:02 +0200 Subject: [PATCH] Request local network permissions inline --- .../eu/faircode/email/FragmentAccount.java | 47 +++++++++++++++--- .../eu/faircode/email/FragmentIdentity.java | 48 ++++++++++++++++--- .../eu/faircode/email/FragmentMessages.java | 2 + .../java/eu/faircode/email/FragmentPop.java | 47 +++++++++++++++--- 4 files changed, 126 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/eu/faircode/email/FragmentAccount.java b/app/src/main/java/eu/faircode/email/FragmentAccount.java index 996b2e91b6..8aa3fc5906 100644 --- a/app/src/main/java/eu/faircode/email/FragmentAccount.java +++ b/app/src/main/java/eu/faircode/email/FragmentAccount.java @@ -2167,19 +2167,54 @@ public class FragmentAccount extends FragmentBase { }.execute(this, args, "account:delete"); } + private Snackbar lanSnackbar = null; + private void checkLan(String host) { - String msg = null; - if (!TextUtils.isEmpty(host)) + boolean lan = false; + if (!TextUtils.isEmpty(host) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.CINNAMON_BUN) try { Context context = getContext(); InetAddress addr = InetAddress.getByName(host); - if ((addr.isSiteLocalAddress() || addr.isLinkLocalAddress() || addr.isLoopbackAddress()) && - !Helper.hasPermission(context, Manifest.permission.ACCESS_LOCAL_NETWORK)) - msg = context.getString(R.string.title_lan); + lan = (addr.isSiteLocalAddress() || addr.isLinkLocalAddress() || addr.isLoopbackAddress()) && + !Helper.hasPermission(context, Manifest.permission.ACCESS_LOCAL_NETWORK); } catch (Throwable ignored) { } - etHost.setError(msg); + if (lan && lanSnackbar == null) { + lanSnackbar = Helper.setSnackbarOptions(Snackbar.make(view, R.string.title_lan_required, Snackbar.LENGTH_INDEFINITE)); + Helper.setSnackbarLines(lanSnackbar, 2); + lanSnackbar.setAction(R.string.title_fix, new View.OnClickListener() { + @Override + public void onClick(View v) { + lanSnackbar.dismiss(); + if (BuildConfig.PLAY_STORE_RELEASE) + Helper.viewFAQ(v.getContext(), 210); + else + requestPermissions(new String[]{Manifest.permission.ACCESS_LOCAL_NETWORK}, REQUEST_PERMISSIONS); + } + }); + lanSnackbar.addCallback(new Snackbar.Callback() { + @Override + public void onShown(Snackbar sb) { + view.requestApplyInsets(); + } + + @Override + public void onDismissed(Snackbar transientBottomBar, int event) { + view.requestApplyInsets(); + } + }); + lanSnackbar.show(); + } else if (!lan && lanSnackbar != null) { + lanSnackbar.dismiss(); + lanSnackbar = null; + } + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + Editable e = etHost.getText(); + checkLan(e == null ? null : e.toString()); } private void setFolders(List _folders, EntityAccount account) { diff --git a/app/src/main/java/eu/faircode/email/FragmentIdentity.java b/app/src/main/java/eu/faircode/email/FragmentIdentity.java index 095e72126c..8bae455e5a 100644 --- a/app/src/main/java/eu/faircode/email/FragmentIdentity.java +++ b/app/src/main/java/eu/faircode/email/FragmentIdentity.java @@ -33,6 +33,7 @@ import android.database.Cursor; import android.graphics.Color; import android.graphics.Paint; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.provider.ContactsContract; import android.text.Editable; @@ -1646,6 +1647,12 @@ public class FragmentIdentity extends FragmentBase { } } + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + Editable e = etHost.getText(); + checkLan(e == null ? null : e.toString()); + } + private void onDelete() { Bundle args = new Bundle(); args.putLong("id", id); @@ -1708,19 +1715,48 @@ public class FragmentIdentity extends FragmentBase { }.execute(this, args, "identity:signature"); } + private Snackbar lanSnackbar = null; + private void checkLan(String host) { - String msg = null; - if (!TextUtils.isEmpty(host)) + boolean lan = false; + if (!TextUtils.isEmpty(host) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.CINNAMON_BUN) try { Context context = getContext(); InetAddress addr = InetAddress.getByName(host); - if ((addr.isSiteLocalAddress() || addr.isLinkLocalAddress() || addr.isLoopbackAddress()) && - !Helper.hasPermission(context, Manifest.permission.ACCESS_LOCAL_NETWORK)) - msg = context.getString(R.string.title_lan); + lan = (addr.isSiteLocalAddress() || addr.isLinkLocalAddress() || addr.isLoopbackAddress()) && + !Helper.hasPermission(context, Manifest.permission.ACCESS_LOCAL_NETWORK); } catch (Throwable ignored) { } - etHost.setError(msg); + if (lan && lanSnackbar == null) { + lanSnackbar = Helper.setSnackbarOptions(Snackbar.make(view, R.string.title_lan_required, Snackbar.LENGTH_INDEFINITE)); + Helper.setSnackbarLines(lanSnackbar, 2); + lanSnackbar.setAction(R.string.title_fix, new View.OnClickListener() { + @Override + public void onClick(View v) { + lanSnackbar.dismiss(); + if (BuildConfig.PLAY_STORE_RELEASE) + Helper.viewFAQ(v.getContext(), 210); + else + requestPermissions(new String[]{Manifest.permission.ACCESS_LOCAL_NETWORK}, REQUEST_PERMISSIONS); + } + }); + lanSnackbar.addCallback(new Snackbar.Callback() { + @Override + public void onShown(Snackbar sb) { + view.requestApplyInsets(); + } + + @Override + public void onDismissed(Snackbar transientBottomBar, int event) { + view.requestApplyInsets(); + } + }); + lanSnackbar.show(); + } else if (!lan && lanSnackbar != null) { + lanSnackbar.dismiss(); + lanSnackbar = null; + } } private void onPickUri(Intent intent) { diff --git a/app/src/main/java/eu/faircode/email/FragmentMessages.java b/app/src/main/java/eu/faircode/email/FragmentMessages.java index 428b340ba6..7618de6b62 100644 --- a/app/src/main/java/eu/faircode/email/FragmentMessages.java +++ b/app/src/main/java/eu/faircode/email/FragmentMessages.java @@ -6410,6 +6410,8 @@ public class FragmentMessages extends FragmentBase new SimpleTask() { @Override protected Boolean onExecute(Context context, Bundle args) throws Throwable { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.CINNAMON_BUN) + return false; if (Helper.hasPermission(context, Manifest.permission.ACCESS_LOCAL_NETWORK)) return false; diff --git a/app/src/main/java/eu/faircode/email/FragmentPop.java b/app/src/main/java/eu/faircode/email/FragmentPop.java index 597ba7b1ed..54bff2c2c3 100644 --- a/app/src/main/java/eu/faircode/email/FragmentPop.java +++ b/app/src/main/java/eu/faircode/email/FragmentPop.java @@ -1167,6 +1167,12 @@ public class FragmentPop extends FragmentBase { } } + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + Editable e = etHost.getText(); + checkLan(e == null ? null : e.toString()); + } + private void onImageSelected(Uri uri) { final Context context = getContext(); @@ -1225,19 +1231,48 @@ public class FragmentPop extends FragmentBase { }.execute(this, args, "account:delete"); } + private Snackbar lanSnackbar = null; + private void checkLan(String host) { - String msg = null; - if (!TextUtils.isEmpty(host)) + boolean lan = false; + if (!TextUtils.isEmpty(host) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.CINNAMON_BUN) try { Context context = getContext(); InetAddress addr = InetAddress.getByName(host); - if ((addr.isSiteLocalAddress() || addr.isLinkLocalAddress() || addr.isLoopbackAddress()) && - !Helper.hasPermission(context, Manifest.permission.ACCESS_LOCAL_NETWORK)) - msg = context.getString(R.string.title_lan); + lan = (addr.isSiteLocalAddress() || addr.isLinkLocalAddress() || addr.isLoopbackAddress()) && + !Helper.hasPermission(context, Manifest.permission.ACCESS_LOCAL_NETWORK); } catch (Throwable ignored) { } - etHost.setError(msg); + if (lan && lanSnackbar == null) { + lanSnackbar = Helper.setSnackbarOptions(Snackbar.make(view, R.string.title_lan_required, Snackbar.LENGTH_INDEFINITE)); + Helper.setSnackbarLines(lanSnackbar, 2); + lanSnackbar.setAction(R.string.title_fix, new View.OnClickListener() { + @Override + public void onClick(View v) { + lanSnackbar.dismiss(); + if (BuildConfig.PLAY_STORE_RELEASE) + Helper.viewFAQ(v.getContext(), 210); + else + requestPermissions(new String[]{Manifest.permission.ACCESS_LOCAL_NETWORK}, REQUEST_PERMISSIONS); + } + }); + lanSnackbar.addCallback(new Snackbar.Callback() { + @Override + public void onShown(Snackbar sb) { + view.requestApplyInsets(); + } + + @Override + public void onDismissed(Snackbar transientBottomBar, int event) { + view.requestApplyInsets(); + } + }); + lanSnackbar.show(); + } else if (!lan && lanSnackbar != null) { + lanSnackbar.dismiss(); + lanSnackbar = null; + } } private List getSwipeActions(Context context) {