Эх сурвалжийг харах

add ability to enter own phone number when enabling address book sync

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
Marcel Hibbe 4 жил өмнө
parent
commit
6a18b9b745

+ 1 - 0
CHANGELOG.md

@@ -7,6 +7,7 @@ Types of changes can be: Added/Changed/Deprecated/Removed/Fixed/Security
 
 
 ## [Unreleased]
 ## [Unreleased]
 ### Added
 ### Added
+- add ability to enter own phone number when address book sync is enabled
 
 
 ### Fixed
 ### Fixed
 - show links for deck-cards
 - show links for deck-cards

+ 10 - 0
app/src/main/java/com/nextcloud/talk/api/NcApi.java

@@ -227,6 +227,16 @@ public interface NcApi {
     @GET
     @GET
     Observable<UserProfileOverall> getUserProfile(@Header("Authorization") String authorization, @Url String url);
     Observable<UserProfileOverall> getUserProfile(@Header("Authorization") String authorization, @Url String url);
 
 
+
+    @GET
+    Observable<UserProfileOverall> getUserData(@Header("Authorization") String authorization, @Url String url);
+
+    @FormUrlEncoded
+    @PUT
+    Observable<GenericOverall> setUserData(@Header("Authorization") String authorization, @Url String url,
+                                                  @Field("key") String key, @Field("value") String value);
+
+
     /*
     /*
         Server URL is: baseUrl + /status.php
         Server URL is: baseUrl + /status.php
      */
      */

+ 171 - 30
app/src/main/java/com/nextcloud/talk/controllers/SettingsController.java

@@ -24,20 +24,37 @@ import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorListenerAdapter;
 import android.app.KeyguardManager;
 import android.app.KeyguardManager;
 import android.content.Context;
 import android.content.Context;
+import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager;
+import android.content.res.ColorStateList;
 import android.net.Uri;
 import android.net.Uri;
 import android.os.Build;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Bundle;
 import android.security.KeyChain;
 import android.security.KeyChain;
+import android.text.Editable;
+import android.text.InputType;
 import android.text.TextUtils;
 import android.text.TextUtils;
+import android.text.TextWatcher;
 import android.util.Log;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewGroup;
 import android.view.WindowManager;
 import android.view.WindowManager;
+import android.widget.Button;
 import android.widget.Checkable;
 import android.widget.Checkable;
+import android.widget.EditText;
+import android.widget.LinearLayout;
 import android.widget.TextView;
 import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AlertDialog;
+import androidx.core.view.ViewCompat;
+import androidx.emoji.widget.EmojiTextView;
+import androidx.work.OneTimeWorkRequest;
+import androidx.work.WorkManager;
 
 
 import com.bluelinelabs.conductor.Controller;
 import com.bluelinelabs.conductor.Controller;
 import com.bluelinelabs.conductor.RouterTransaction;
 import com.bluelinelabs.conductor.RouterTransaction;
@@ -48,6 +65,7 @@ import com.facebook.drawee.backends.pipeline.Fresco;
 import com.facebook.drawee.interfaces.DraweeController;
 import com.facebook.drawee.interfaces.DraweeController;
 import com.facebook.drawee.view.SimpleDraweeView;
 import com.facebook.drawee.view.SimpleDraweeView;
 import com.google.android.material.snackbar.Snackbar;
 import com.google.android.material.snackbar.Snackbar;
+import com.google.android.material.textfield.TextInputLayout;
 import com.nextcloud.talk.BuildConfig;
 import com.nextcloud.talk.BuildConfig;
 import com.nextcloud.talk.R;
 import com.nextcloud.talk.R;
 import com.nextcloud.talk.api.NcApi;
 import com.nextcloud.talk.api.NcApi;
@@ -58,6 +76,7 @@ import com.nextcloud.talk.jobs.ContactAddressBookWorker;
 import com.nextcloud.talk.models.RingtoneSettings;
 import com.nextcloud.talk.models.RingtoneSettings;
 import com.nextcloud.talk.models.database.UserEntity;
 import com.nextcloud.talk.models.database.UserEntity;
 import com.nextcloud.talk.models.json.generic.GenericOverall;
 import com.nextcloud.talk.models.json.generic.GenericOverall;
+import com.nextcloud.talk.models.json.userprofile.UserProfileOverall;
 import com.nextcloud.talk.utils.ApiUtils;
 import com.nextcloud.talk.utils.ApiUtils;
 import com.nextcloud.talk.utils.DisplayUtils;
 import com.nextcloud.talk.utils.DisplayUtils;
 import com.nextcloud.talk.utils.DoNotDisturbUtils;
 import com.nextcloud.talk.utils.DoNotDisturbUtils;
@@ -90,12 +109,6 @@ import java.util.Objects;
 
 
 import javax.inject.Inject;
 import javax.inject.Inject;
 
 
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.core.view.ViewCompat;
-import androidx.emoji.widget.EmojiTextView;
-import androidx.work.OneTimeWorkRequest;
-import androidx.work.WorkManager;
 import autodagger.AutoInjector;
 import autodagger.AutoInjector;
 import butterknife.BindView;
 import butterknife.BindView;
 import butterknife.OnClick;
 import butterknife.OnClick;
@@ -160,7 +173,7 @@ public class SettingsController extends BaseController {
     @BindView(R.id.settings_screen_lock_timeout)
     @BindView(R.id.settings_screen_lock_timeout)
     MaterialChoicePreference screenLockTimeoutChoicePreference;
     MaterialChoicePreference screenLockTimeoutChoicePreference;
     @BindView(R.id.settings_phone_book_integration)
     @BindView(R.id.settings_phone_book_integration)
-    MaterialSwitchPreference phoneBookIntegretationPreference;
+    MaterialSwitchPreference phoneBookIntegrationPreference;
     @BindView(R.id.settings_read_privacy)
     @BindView(R.id.settings_read_privacy)
     MaterialSwitchPreference readPrivacyPreference;
     MaterialSwitchPreference readPrivacyPreference;
 
 
@@ -313,11 +326,11 @@ public class SettingsController extends BaseController {
                     SwitchAccountController()).pushChangeHandler(new VerticalChangeHandler())
                     SwitchAccountController()).pushChangeHandler(new VerticalChangeHandler())
                     .popChangeHandler(new VerticalChangeHandler()));
                     .popChangeHandler(new VerticalChangeHandler()));
         });
         });
-        
+
         if (userUtils.getCurrentUser().isPhoneBookIntegrationAvailable()) {
         if (userUtils.getCurrentUser().isPhoneBookIntegrationAvailable()) {
-            phoneBookIntegretationPreference.setVisibility(View.VISIBLE);
+            phoneBookIntegrationPreference.setVisibility(View.VISIBLE);
         } else {
         } else {
-            phoneBookIntegretationPreference.setVisibility(View.GONE);
+            phoneBookIntegrationPreference.setVisibility(View.GONE);
         }
         }
 
 
         String host = null;
         String host = null;
@@ -464,7 +477,7 @@ public class SettingsController extends BaseController {
         }
         }
 
 
         ((Checkable) linkPreviewsSwitchPreference.findViewById(R.id.mp_checkable)).setChecked(appPreferences.getAreLinkPreviewsAllowed());
         ((Checkable) linkPreviewsSwitchPreference.findViewById(R.id.mp_checkable)).setChecked(appPreferences.getAreLinkPreviewsAllowed());
-        ((Checkable) phoneBookIntegretationPreference.findViewById(R.id.mp_checkable)).setChecked(appPreferences.isPhoneBookIntegrationEnabled());
+        ((Checkable) phoneBookIntegrationPreference.findViewById(R.id.mp_checkable)).setChecked(appPreferences.isPhoneBookIntegrationEnabled());
 
 
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
             KeyguardManager keyguardManager = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
             KeyguardManager keyguardManager = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
@@ -741,20 +754,20 @@ public class SettingsController extends BaseController {
 
 
     @Override
     @Override
     public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
     public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
-       if (requestCode == ContactAddressBookWorker.REQUEST_PERMISSION && 
-               grantResults.length > 0 && 
-               grantResults[0] == PackageManager.PERMISSION_GRANTED) {
-           WorkManager
-                   .getInstance()
-                   .enqueue(new OneTimeWorkRequest.Builder(ContactAddressBookWorker.class).build());
-       } else {
-           appPreferences.setPhoneBookIntegration(false);
-           ((Checkable) phoneBookIntegretationPreference.findViewById(R.id.mp_checkable)).setChecked(appPreferences.isPhoneBookIntegrationEnabled());
-           Snackbar.make(getView(), 
-                   context.getResources().getString(R.string.no_phone_book_integration_due_to_permissions), 
-                   Snackbar.LENGTH_LONG)
-                   .show();
-       }
+        if (requestCode == ContactAddressBookWorker.REQUEST_PERMISSION &&
+                grantResults.length > 0 &&
+                grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+            WorkManager
+                    .getInstance()
+                    .enqueue(new OneTimeWorkRequest.Builder(ContactAddressBookWorker.class).build());
+            checkForPhoneNumber();
+        } else {
+            appPreferences.setPhoneBookIntegration(false);
+            ((Checkable) phoneBookIntegrationPreference.findViewById(R.id.mp_checkable)).setChecked(appPreferences.isPhoneBookIntegrationEnabled());
+            Toast.makeText(context, context.getResources().getString(
+                    R.string.no_phone_book_integration_due_to_permissions),
+                    Toast.LENGTH_LONG).show();
+        }
     }
     }
 
 
     private class ScreenLockTimeoutListener implements OnPreferenceValueChangedListener<String> {
     private class ScreenLockTimeoutListener implements OnPreferenceValueChangedListener<String> {
@@ -847,22 +860,150 @@ public class SettingsController extends BaseController {
             NextcloudTalkApplication.Companion.setAppTheme(newValue);
             NextcloudTalkApplication.Companion.setAppTheme(newValue);
         }
         }
     }
     }
-    
+
     private class PhoneBookIntegrationChangeListener implements OnPreferenceValueChangedListener<Boolean> {
     private class PhoneBookIntegrationChangeListener implements OnPreferenceValueChangedListener<Boolean> {
         private final Controller controller;
         private final Controller controller;
-        
+
         public PhoneBookIntegrationChangeListener(Controller controller) {
         public PhoneBookIntegrationChangeListener(Controller controller) {
             this.controller = controller;
             this.controller = controller;
         }
         }
-        
+
         @Override
         @Override
         public void onChanged(Boolean newValue) {
         public void onChanged(Boolean newValue) {
             if (newValue) {
             if (newValue) {
-                ContactAddressBookWorker.Companion.checkPermission(controller, context);
+                if(ContactAddressBookWorker.Companion.checkPermission(controller, context)){
+                    checkForPhoneNumber();
+                }
             }
             }
         }
         }
     }
     }
-    
+
+    private void checkForPhoneNumber() {
+        ncApi.getUserData(
+                ApiUtils.getCredentials(currentUser.getUsername(), currentUser.getToken()),
+                ApiUtils.getUrlForUserProfile(currentUser.getBaseUrl())
+        ).subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe(new Observer<UserProfileOverall>() {
+
+                    @Override
+                    public void onSubscribe(@io.reactivex.annotations.NonNull Disposable d) {
+
+                    }
+
+                    @Override
+                    public void onNext(@io.reactivex.annotations.NonNull UserProfileOverall userProfileOverall) {
+                        if (userProfileOverall.getOcs().getData().getPhone().isEmpty()) {
+                            askForPhoneNumber();
+                        } else {
+                            Log.d(TAG, "phone number already set");
+                        }
+                    }
+
+                    @Override
+                    public void onError(@io.reactivex.annotations.NonNull Throwable e) {
+
+                    }
+
+                    @Override
+                    public void onComplete() {
+
+                    }
+                });
+    }
+
+    private void askForPhoneNumber() {
+        final LinearLayout phoneNumberLayoutWrapper = new LinearLayout(getActivity());
+        phoneNumberLayoutWrapper.setOrientation(LinearLayout.VERTICAL);
+        phoneNumberLayoutWrapper.setPadding(50, 0, 50, 0);
+
+        final TextInputLayout phoneNumberInputLayout = new TextInputLayout(getActivity());
+        final EditText phoneNumberField = new EditText(getActivity());
+
+        phoneNumberInputLayout.setHelperTextColor(ColorStateList.valueOf(getResources().getColor(R.color.nc_darkRed)));
+        phoneNumberField.setInputType(InputType.TYPE_CLASS_PHONE);
+        phoneNumberField.setText("+");
+        phoneNumberField.addTextChangedListener(new TextWatcher() {
+            public void afterTextChanged(Editable s) {
+            }
+
+            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+            }
+
+            public void onTextChanged(CharSequence s, int start, int before, int count) {
+                phoneNumberInputLayout.setHelperText("");
+            }
+        });
+
+        phoneNumberInputLayout.addView(phoneNumberField);
+        phoneNumberLayoutWrapper.addView(phoneNumberInputLayout);
+
+        AlertDialog dialog = new AlertDialog.Builder(getActivity())
+                .setTitle(R.string.nc_settings_phone_book_integration_phone_number_dialog_title)
+                .setMessage(R.string.nc_settings_phone_book_integration_phone_number_dialog_description)
+                .setView(phoneNumberLayoutWrapper)
+                .setPositiveButton(context.getResources().getString(R.string.nc_common_set), null)
+                .setNegativeButton(context.getResources().getString(R.string.nc_common_skip), null)
+                .create();
+
+        dialog.setOnShowListener(new DialogInterface.OnShowListener() {
+            @Override
+            public void onShow(DialogInterface dialogInterface) {
+                Button button = ((AlertDialog) dialog).getButton(AlertDialog.BUTTON_POSITIVE);
+                button.setOnClickListener(new View.OnClickListener() {
+                    @Override
+                    public void onClick(View view) {
+                        setPhoneNumber(phoneNumberInputLayout, dialog);
+                    }
+                });
+            }
+        });
+        dialog.show();
+    }
+
+    private void setPhoneNumber(TextInputLayout textInputLayout, AlertDialog dialog) {
+        String phoneNumber = textInputLayout.getEditText().getText().toString();
+
+        ncApi.setUserData(ApiUtils.getCredentials(currentUser.getUsername(), currentUser.getToken()),
+                ApiUtils.getUrlForUserData(currentUser.getBaseUrl(), currentUser.getUserId()), "phone", phoneNumber
+        ).subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe(new Observer<GenericOverall>() {
+
+                    @Override
+                    public void onSubscribe(@io.reactivex.annotations.NonNull Disposable d) {
+
+                    }
+
+                    @Override
+                    public void onNext(@io.reactivex.annotations.NonNull GenericOverall genericOverall) {
+                        int statusCode = genericOverall.ocs.meta.statusCode;
+                        if (statusCode == 200) {
+                            dialog.dismiss();
+                            Toast.makeText(context, context.getResources().getString(
+                                    R.string.nc_settings_phone_book_integration_phone_number_dialog_success),
+                                    Toast.LENGTH_LONG).show();
+                        } else {
+                            textInputLayout.setHelperText(context.getResources().getString(
+                                    R.string.nc_settings_phone_book_integration_phone_number_dialog_invalid));
+                            Log.d(TAG, "failed to set phoneNumber. statusCode=" + statusCode);
+                        }
+
+                    }
+
+                    @Override
+                    public void onError(@io.reactivex.annotations.NonNull Throwable e) {
+                        textInputLayout.setHelperText(context.getResources().getString(
+                                R.string.nc_settings_phone_book_integration_phone_number_dialog_invalid));
+                        Log.e(TAG, "setPhoneNumber error", e);
+                    }
+
+                    @Override
+                    public void onComplete() {
+                    }
+                });
+    }
+
     private class ReadPrivacyChangeListener implements OnPreferenceValueChangedListener<Boolean> {
     private class ReadPrivacyChangeListener implements OnPreferenceValueChangedListener<Boolean> {
         @Override
         @Override
         public void onChanged(Boolean newValue) {
         public void onChanged(Boolean newValue) {

+ 3 - 1
app/src/main/java/com/nextcloud/talk/jobs/ContactAddressBookWorker.kt

@@ -366,19 +366,21 @@ class ContactAddressBookWorker(val context: Context, workerParameters: WorkerPar
             }
             }
         }
         }
 
 
-        fun checkPermission(controller: Controller, context: Context) {
+        fun checkPermission(controller: Controller, context: Context): Boolean {
             if (ContextCompat.checkSelfPermission(context,
             if (ContextCompat.checkSelfPermission(context,
                             Manifest.permission.WRITE_CONTACTS) != PackageManager.PERMISSION_GRANTED ||
                             Manifest.permission.WRITE_CONTACTS) != PackageManager.PERMISSION_GRANTED ||
                     ContextCompat.checkSelfPermission(context,
                     ContextCompat.checkSelfPermission(context,
                             Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
                             Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
                 controller.requestPermissions(arrayOf(Manifest.permission.WRITE_CONTACTS,
                 controller.requestPermissions(arrayOf(Manifest.permission.WRITE_CONTACTS,
                         Manifest.permission.READ_CONTACTS), REQUEST_PERMISSION)
                         Manifest.permission.READ_CONTACTS), REQUEST_PERMISSION)
+                return false
             } else {
             } else {
                 WorkManager
                 WorkManager
                         .getInstance()
                         .getInstance()
                         .enqueue(OneTimeWorkRequest.Builder(ContactAddressBookWorker::class.java)
                         .enqueue(OneTimeWorkRequest.Builder(ContactAddressBookWorker::class.java)
                                 .setInputData(Data.Builder().putBoolean(KEY_FORCE, true).build())
                                 .setInputData(Data.Builder().putBoolean(KEY_FORCE, true).build())
                                 .build())
                                 .build())
+                return true
             }
             }
         }
         }
     }
     }

+ 3 - 0
app/src/main/java/com/nextcloud/talk/models/json/userprofile/UserProfileData.java

@@ -37,4 +37,7 @@ public class UserProfileData {
 
 
     @JsonField(name = "id")
     @JsonField(name = "id")
     String userId;
     String userId;
+
+    @JsonField(name = "phone")
+    String phone;
 }
 }

+ 4 - 0
app/src/main/java/com/nextcloud/talk/utils/ApiUtils.java

@@ -229,6 +229,10 @@ public class ApiUtils {
         return baseUrl + ocsApiVersion + "/cloud/user";
         return baseUrl + ocsApiVersion + "/cloud/user";
     }
     }
 
 
+    public static String getUrlForUserData(String baseUrl, String userId) {
+        return baseUrl + ocsApiVersion + "/cloud/users/" + userId;
+    }
+
     public static String getUrlForUserSettings(String baseUrl) {
     public static String getUrlForUserSettings(String baseUrl) {
         return baseUrl + ocsApiVersion + spreedApiVersion + "/settings/user";
         return baseUrl + ocsApiVersion + spreedApiVersion + "/settings/user";
     }
     }

+ 7 - 0
app/src/main/res/values/strings.xml

@@ -22,6 +22,8 @@
     <!-- Common -->
     <!-- Common -->
     <string name="nc_yes">Yes</string>
     <string name="nc_yes">Yes</string>
     <string name="nc_no">No</string>
     <string name="nc_no">No</string>
+    <string name="nc_common_skip">Skip</string>
+    <string name="nc_common_set">Set</string>
     <string name="nc_common_error_sorry">Sorry, something went wrong!</string>
     <string name="nc_common_error_sorry">Sorry, something went wrong!</string>
 
 
     <!-- Bottom Navigation -->
     <!-- Bottom Navigation -->
@@ -344,6 +346,11 @@
     <string name="nc_settings_phone_book_integration_key" translatable="false">phone_book_integration</string>
     <string name="nc_settings_phone_book_integration_key" translatable="false">phone_book_integration</string>
     <string name="nc_settings_phone_book_integration_desc">Match contacts based on phone number to integrate Talk shortcut in phone book</string>
     <string name="nc_settings_phone_book_integration_desc">Match contacts based on phone number to integrate Talk shortcut in phone book</string>
     <string name="nc_settings_phone_book_integration_title">Phone book integration</string>
     <string name="nc_settings_phone_book_integration_title">Phone book integration</string>
+    <string name="nc_settings_phone_book_integration_phone_number_dialog_title">Phone number</string>
+    <string name="nc_settings_phone_book_integration_phone_number_dialog_description">You can set your phone number so
+        other users will be able to find you</string>
+    <string name="nc_settings_phone_book_integration_phone_number_dialog_invalid">Invalid phone number</string>
+    <string name="nc_settings_phone_book_integration_phone_number_dialog_success">Phone number set successfully</string>
     <string name="no_phone_book_integration_due_to_permissions">No phone book integration due to missing permissions</string>
     <string name="no_phone_book_integration_due_to_permissions">No phone book integration due to missing permissions</string>
 
 
     <!-- Non-translatable strings -->
     <!-- Non-translatable strings -->