AndroidTV: Add profile edition from main screen
User can now update his displayed name and his picture
Tuleap-Id: #1780
Change-Id: I8b917031ed8d8fd1ac4e02fbb6a85b79cdb1b518
diff --git a/ring-android/app/src/main/AndroidManifest.xml b/ring-android/app/src/main/AndroidManifest.xml
index 2e1e235..c0b59e1 100644
--- a/ring-android/app/src/main/AndroidManifest.xml
+++ b/ring-android/app/src/main/AndroidManifest.xml
@@ -271,6 +271,9 @@
android:name="cx.ring.tv.about.AboutActivity"
android:theme="@style/Theme.Leanback" />
+ <activity android:name="cx.ring.tv.account.TVProfileEditingActivity"
+ android:theme="@style/Theme.Leanback"/>
+
<activity
android:name="cx.ring.tv.call.TVCallActivity"
android:theme="@style/AppThemeBase">
diff --git a/ring-android/app/src/main/java/cx/ring/dependencyinjection/RingInjectionComponent.java b/ring-android/app/src/main/java/cx/ring/dependencyinjection/RingInjectionComponent.java
index c92f923..f37ba49 100755
--- a/ring-android/app/src/main/java/cx/ring/dependencyinjection/RingInjectionComponent.java
+++ b/ring-android/app/src/main/java/cx/ring/dependencyinjection/RingInjectionComponent.java
@@ -66,6 +66,7 @@
import cx.ring.tv.account.TVAccountWizard;
import cx.ring.tv.account.TVHomeAccountCreationFragment;
import cx.ring.tv.account.TVProfileCreationFragment;
+import cx.ring.tv.account.TVProfileEditingFragment;
import cx.ring.tv.account.TVRingAccountCreationFragment;
import cx.ring.tv.account.TVRingLinkAccountFragment;
import cx.ring.tv.call.TVCallActivity;
@@ -186,6 +187,8 @@
void inject(TVLaunchActivity activity);
+ void inject(TVProfileEditingFragment activity);
+
void inject(TVContactRequestFragment fragment);
}
diff --git a/ring-android/app/src/main/java/cx/ring/navigation/RingNavigationFragment.java b/ring-android/app/src/main/java/cx/ring/navigation/RingNavigationFragment.java
index 0974ee6..cff7d45 100644
--- a/ring-android/app/src/main/java/cx/ring/navigation/RingNavigationFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/navigation/RingNavigationFragment.java
@@ -347,10 +347,11 @@
mSourcePhoto.compress(Bitmap.CompressFormat.PNG, 100, stream);
Photo photo = new Photo(stream.toByteArray(), ImageType.PNG);
- presenter.saveVCard(editText.getText().toString().trim(), photo);
+ presenter.saveVCardFormattedName(editText.getText().toString().trim());
+ presenter.saveVCardPhoto(photo);
mSourcePhoto = null;
} else {
- presenter.saveVCard(editText.getText().toString().trim());
+ presenter.saveVCardFormattedName(editText.getText().toString().trim());
}
}
});
diff --git a/ring-android/app/src/main/java/cx/ring/tv/account/TVProfileEditingActivity.java b/ring-android/app/src/main/java/cx/ring/tv/account/TVProfileEditingActivity.java
new file mode 100644
index 0000000..61beb02
--- /dev/null
+++ b/ring-android/app/src/main/java/cx/ring/tv/account/TVProfileEditingActivity.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2017 Savoir-faire Linux Inc.
+ *
+ * Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+package cx.ring.tv.account;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.os.Bundle;
+
+import cx.ring.R;
+
+import static cx.ring.tv.account.TVProfileEditingFragment.REQUEST_CODE_GALLERY;
+import static cx.ring.tv.account.TVProfileEditingFragment.REQUEST_CODE_PHOTO;
+
+public class TVProfileEditingActivity extends Activity {
+
+ public static final String TAG = TVProfileEditingActivity.class.getSimpleName();
+ private static final String TV_PROFILE_EDITING_TAG = "tv_profile_editing";
+ private TVProfileEditingFragment fTvProfileEditing;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.tv_activity_profile_editing);
+
+ if (savedInstanceState != null) {
+ fTvProfileEditing = (TVProfileEditingFragment) getFragmentManager().findFragmentByTag(TV_PROFILE_EDITING_TAG);
+ }
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+
+ switch (requestCode) {
+ case REQUEST_CODE_PHOTO:
+ if (resultCode == RESULT_OK && data != null && data.getExtras() != null) {
+ fTvProfileEditing.updatePhoto((Bitmap) data.getExtras().get("data"));
+ }
+ break;
+ case REQUEST_CODE_GALLERY:
+ if (resultCode == RESULT_OK && data != null) {
+ fTvProfileEditing.updatePhoto(data.getData());
+ }
+ break;
+ }
+ }
+}
diff --git a/ring-android/app/src/main/java/cx/ring/tv/account/TVProfileEditingFragment.java b/ring-android/app/src/main/java/cx/ring/tv/account/TVProfileEditingFragment.java
new file mode 100644
index 0000000..f14f42e
--- /dev/null
+++ b/ring-android/app/src/main/java/cx/ring/tv/account/TVProfileEditingFragment.java
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2017 Savoir-faire Linux Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package cx.ring.tv.account;
+
+import android.Manifest;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.ActivityNotFoundException;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.MediaStore;
+import android.support.annotation.NonNull;
+import android.support.v17.leanback.app.GuidedStepFragment;
+import android.support.v17.leanback.widget.GuidanceStylist;
+import android.support.v17.leanback.widget.GuidedAction;
+import android.support.v4.app.ActivityCompat;
+import android.util.Log;
+import android.view.View;
+
+import java.io.ByteArrayOutputStream;
+import java.util.List;
+
+import cx.ring.R;
+import cx.ring.account.ProfileCreationFragment;
+import cx.ring.adapters.ContactDetailsTask;
+import cx.ring.application.RingApplication;
+import cx.ring.navigation.RingNavigationPresenter;
+import cx.ring.navigation.RingNavigationView;
+import cx.ring.navigation.RingNavigationViewModel;
+import cx.ring.tv.camera.CustomCameraActivity;
+import cx.ring.utils.BitmapUtils;
+import cx.ring.utils.VCardUtils;
+import ezvcard.VCard;
+import ezvcard.parameter.ImageType;
+import ezvcard.property.Photo;
+
+public class TVProfileEditingFragment extends RingGuidedStepFragment<RingNavigationPresenter>
+ implements RingNavigationView {
+
+ public static final int REQUEST_CODE_PHOTO = 1;
+ public static final int REQUEST_CODE_GALLERY = 2;
+ public static final int REQUEST_PERMISSION_CAMERA = 3;
+ public static final int REQUEST_PERMISSION_READ_STORAGE = 4;
+ private static final int USER_NAME = 1;
+ private static final int GALLERY = 2;
+ private static final int CAMERA = 3;
+
+ private List<GuidedAction> actions;
+
+ public static GuidedStepFragment newInstance() {
+ return new TVProfileEditingFragment();
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ switch (requestCode) {
+ case ProfileCreationFragment.REQUEST_CODE_PHOTO:
+ if (resultCode == Activity.RESULT_OK && data != null) {
+ Bundle extras = data.getExtras();
+ if (extras == null) {
+ Log.e(TAG, "onActivityResult: Not able to get picture from extra");
+ return;
+ }
+ byte[] input = extras.getByteArray("data");
+ if (input == null) {
+ Log.e(TAG, "onActivityResult: Not able to get byte[] from extra");
+ return;
+ }
+ Bitmap original = BitmapFactory.decodeByteArray(input, 0, input.length);
+ updatePhoto(original);
+ }
+ break;
+ case ProfileCreationFragment.REQUEST_CODE_GALLERY:
+ if (resultCode == Activity.RESULT_OK && data != null) {
+ updatePhoto(data.getData());
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ ((RingApplication) getActivity().getApplication()).getRingInjectionComponent().inject(this);
+ super.onViewCreated(view, savedInstanceState);
+ presenter.updateUser();
+ }
+
+ @Override
+ @NonNull
+ public GuidanceStylist.Guidance onCreateGuidance(Bundle savedInstanceState) {
+ String title = getString(R.string.profile);
+ String breadcrumb = "";
+ String description = getString(R.string.profile_message_warning);
+
+ Drawable icon = getActivity().getResources().getDrawable(R.drawable.ic_contact_picture);
+
+ return new GuidanceStylist.Guidance(title, description, breadcrumb, icon);
+ }
+
+ @Override
+ public int onProvideTheme() {
+ return R.style.Theme_Ring_Leanback_GuidedStep_First;
+ }
+
+ @Override
+ public void onCreateActions(@NonNull List<GuidedAction> actions, Bundle savedInstanceState) {
+ String desc = getString(R.string.account_edit_profile);
+ String editdesc = getString(R.string.profile_name_hint);
+ addEditTextAction(actions, USER_NAME, desc, editdesc, "");
+ addAction(actions, CAMERA, getActivity().getResources().getString(R.string.take_a_photo), "");
+ addAction(actions, GALLERY, getActivity().getResources().getString(R.string.open_the_gallery), "");
+
+ this.actions = actions;
+ }
+
+ public long onGuidedActionEditedAndProceed(GuidedAction action) {
+ if (action.getId() == USER_NAME) {
+ String username = action.getEditDescription().toString();
+ presenter.saveVCardFormattedName(username);
+ } else if (action.getId() == CAMERA) {
+ presenter.cameraClicked();
+ } else if (action.getId() == GALLERY) {
+ presenter.galleryClicked();
+ }
+ return super.onGuidedActionEditedAndProceed(action);
+ }
+
+ @Override
+ public void onGuidedActionClicked(GuidedAction action) {
+ if (action.getId() == CAMERA) {
+ presenter.cameraClicked();
+ } else if (action.getId() == GALLERY) {
+ presenter.galleryClicked();
+ }
+ }
+
+ @Override
+ public void showViewModel(RingNavigationViewModel viewModel) {
+ // displays account available info
+ VCard vcard = viewModel.getVcard(getActivity().getFilesDir());
+ if (vcard == null || vcard.getPhotos().isEmpty()) {
+ getGuidanceStylist().getIconView().setImageDrawable(getActivity().getResources().getDrawable(R.drawable.ic_contact_picture));
+ } else {
+ if (!this.actions.isEmpty() && this.actions.get(0).getId() == USER_NAME) {
+ this.actions.get(0).setEditDescription(vcard.getFormattedName().getValue());
+ }
+
+ Photo tmp = vcard.getPhotos().get(0);
+ Bitmap bitmap = BitmapFactory.decodeByteArray(tmp.getData(), 0, tmp.getData().length);
+ getGuidanceStylist().getIconView().setImageBitmap(bitmap);
+ }
+ }
+
+ @Override
+ public void gotToImageCapture() {
+ Intent intent = new Intent(getActivity(), CustomCameraActivity.class);
+ startActivityForResult(intent, REQUEST_CODE_PHOTO);
+ }
+
+ @Override
+ public void askCameraPermission() {
+ ActivityCompat.requestPermissions(getActivity(),
+ new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE},
+ REQUEST_PERMISSION_CAMERA);
+ }
+
+ @Override
+ public void askGalleryPermission() {
+ ActivityCompat.requestPermissions(getActivity(),
+ new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
+ REQUEST_PERMISSION_READ_STORAGE);
+ }
+
+ @Override
+ public void goToGallery() {
+ try {
+ Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
+ startActivityForResult(intent, REQUEST_CODE_GALLERY);
+ } catch (ActivityNotFoundException e) {
+ new AlertDialog.Builder(getActivity())
+ .setPositiveButton(android.R.string.ok, null)
+ .setTitle(R.string.gallery_error_title)
+ .setMessage(R.string.gallery_error_message)
+ .show();
+ }
+ }
+
+ public void updatePhoto(Uri uriImage) {
+ updatePhoto(ContactDetailsTask.loadProfilePhotoFromUri(getActivity(), uriImage));
+ }
+
+ public void updatePhoto(Bitmap image) {
+ if (image == null) {
+ Log.w(TAG, "updatePhoto: null photo");
+ return;
+ }
+
+ ByteArrayOutputStream stream = new ByteArrayOutputStream();
+ BitmapUtils.reduceBitmap(image, VCardUtils.VCARD_PHOTO_SIZE);
+ image.compress(Bitmap.CompressFormat.PNG, 100, stream);
+ Photo photo = new Photo(stream.toByteArray(), ImageType.PNG);
+
+ presenter.saveVCardPhoto(photo);
+ }
+}
\ No newline at end of file
diff --git a/ring-android/app/src/main/java/cx/ring/tv/cards/Card.java b/ring-android/app/src/main/java/cx/ring/tv/cards/Card.java
index eaa0167..65fcc50 100644
--- a/ring-android/app/src/main/java/cx/ring/tv/cards/Card.java
+++ b/ring-android/app/src/main/java/cx/ring/tv/cards/Card.java
@@ -127,6 +127,7 @@
SEARCH_RESULT,
ABOUT_CONTRIBUTOR,
ACCOUNT_ADD_DEVICE,
+ ACCOUNT_EDIT_PROFILE,
ABOUT_LICENCES,
CONTACT,
CONTACT_ONLINE,
diff --git a/ring-android/app/src/main/java/cx/ring/tv/cards/CardPresenterSelector.java b/ring-android/app/src/main/java/cx/ring/tv/cards/CardPresenterSelector.java
index 24bde1e..1adda08 100644
--- a/ring-android/app/src/main/java/cx/ring/tv/cards/CardPresenterSelector.java
+++ b/ring-android/app/src/main/java/cx/ring/tv/cards/CardPresenterSelector.java
@@ -32,7 +32,7 @@
public class CardPresenterSelector extends PresenterSelector {
private final Context mContext;
- private final HashMap<Card.Type, Presenter> presenters = new HashMap<Card.Type, Presenter>();
+ private final HashMap<Card.Type, Presenter> presenters = new HashMap<>();
public CardPresenterSelector(Context context) {
mContext = context;
@@ -51,6 +51,7 @@
case ABOUT_CONTRIBUTOR:
case ABOUT_LICENCES:
case ACCOUNT_ADD_DEVICE:
+ case ACCOUNT_EDIT_PROFILE:
presenter = new IconCardPresenter(mContext);
break;
case SEARCH_RESULT:
diff --git a/ring-android/app/src/main/java/cx/ring/tv/cards/iconcards/IconCardHelper.java b/ring-android/app/src/main/java/cx/ring/tv/cards/iconcards/IconCardHelper.java
index 9113bb1..6e3bc65 100644
--- a/ring-android/app/src/main/java/cx/ring/tv/cards/iconcards/IconCardHelper.java
+++ b/ring-android/app/src/main/java/cx/ring/tv/cards/iconcards/IconCardHelper.java
@@ -44,12 +44,22 @@
case ABOUT_VERSION:
return getVersionCard(pContext);
case ACCOUNT_ADD_DEVICE:
- return getAccountAddDevice(pContext);
+ return getAccountAddDeviceCard(pContext);
+ case ACCOUNT_EDIT_PROFILE:
+ return getAccountManagementCard(pContext);
default:
return null;
}
}
+ public static IconCard getAccountAddDeviceCard(Context pContext) {
+ return new IconCard(Card.Type.ACCOUNT_ADD_DEVICE, pContext.getString(R.string.account_link_export_button), "", R.drawable.ic_add_white);
+ }
+
+ public static IconCard getAccountManagementCard(Context pContext) {
+ return new IconCard(Card.Type.ACCOUNT_EDIT_PROFILE, pContext.getString(R.string.account_edit_profile), "", R.drawable.ic_account_card_details_white);
+ }
+
public static IconCard getVersionCard(Context pContext) {
return new IconCard(Card.Type.ABOUT_VERSION, pContext.getString(R.string.version_section) + " 1.0" + " " + BuildConfig.VERSION_NAME, "", R.drawable.ic_ring_logo_white);
}
@@ -62,10 +72,6 @@
return new IconCard(Card.Type.ABOUT_CONTRIBUTOR, pContext.getString(R.string.credits), formatContributors(pContext), R.drawable.ic_face);
}
- public static IconCard getAccountAddDevice(Context pContext) {
- return new IconCard(Card.Type.ACCOUNT_ADD_DEVICE, pContext.getString(R.string.account_link_export_button), "", R.drawable.ic_add_white);
- }
-
private static CharSequence formatLicence(Context pContext) {
Resources res = pContext.getResources();
diff --git a/ring-android/app/src/main/java/cx/ring/tv/main/MainFragment.java b/ring-android/app/src/main/java/cx/ring/tv/main/MainFragment.java
index b94f2f5..e994dc6 100644
--- a/ring-android/app/src/main/java/cx/ring/tv/main/MainFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/tv/main/MainFragment.java
@@ -40,6 +40,7 @@
import cx.ring.navigation.RingNavigationViewModel;
import cx.ring.tv.about.AboutActivity;
import cx.ring.tv.account.TVAccountExport;
+import cx.ring.tv.account.TVProfileEditingActivity;
import cx.ring.tv.call.TVCallActivity;
import cx.ring.tv.cards.Card;
import cx.ring.tv.cards.CardListRow;
@@ -55,6 +56,8 @@
import cx.ring.tv.model.TVListViewModel;
import cx.ring.tv.search.SearchActivity;
import cx.ring.tv.views.CustomTitleView;
+import ezvcard.VCard;
+import ezvcard.property.FormattedName;
import ezvcard.property.Photo;
public class MainFragment extends BaseBrowseFragment<MainPresenter> implements MainView {
@@ -155,12 +158,12 @@
}
return new CardListRow(new HeaderItem(HEADER_MISC, titleSection), listRowAdapter, row);
-
}
private Row createMyAccountRow() {
List<Card> cards = new ArrayList<>();
- cards.add(IconCardHelper.getAccountAddDevice(getActivity()));
+ cards.add(IconCardHelper.getAccountAddDeviceCard(getActivity()));
+ cards.add(IconCardHelper.getAccountManagementCard(getActivity()));
return createRow(getString(R.string.ring_account), cards, false);
}
@@ -283,8 +286,19 @@
return;
}
- List<Photo> photos = viewModel.getVcard(getActivity().getFilesDir()).getPhotos();
- if (!photos.isEmpty()) {
+ VCard vcard = viewModel.getVcard(getActivity().getFilesDir());
+ if (vcard == null) {
+ Log.e(TAG, "displayAccountInfos: Not able to get vcard");
+ return;
+ }
+
+ FormattedName formattedName = vcard.getFormattedName();
+ if (formattedName != null) {
+ titleView.setAlias(formattedName.getValue());
+ }
+
+ List<Photo> photos = vcard.getPhotos();
+ if (!photos.isEmpty() && photos.get(0) != null) {
titleView.setCurrentAccountPhoto(photos.get(0).getData());
}
}
@@ -297,6 +311,19 @@
GuidedStepFragment.add(getFragmentManager(), wizard, R.id.main_browse_fragment);
}
+ @Override
+ public void showProfileEditing() {
+ Intent intent = new Intent(getActivity(), TVProfileEditingActivity.class);
+ startActivity(intent);
+ }
+
+ @Override
+ public void showLicence(int aboutType) {
+ Intent intent = new Intent(getActivity(), AboutActivity.class);
+ intent.putExtra("abouttype", aboutType);
+ startActivity(intent);
+ }
+
private final class ItemViewClickedListener implements OnItemViewClickedListener {
@Override
public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item,
@@ -319,14 +346,14 @@
switch (card.getType()) {
case ABOUT_CONTRIBUTOR:
case ABOUT_LICENCES:
- Intent intent = new Intent(getActivity(),
- AboutActivity.class);
- intent.putExtra("abouttype", card.getType().ordinal());
- startActivity(intent);
+ presenter.onLicenceClicked(card.getType().ordinal());
break;
case ACCOUNT_ADD_DEVICE:
presenter.onExportClicked();
break;
+ case ACCOUNT_EDIT_PROFILE:
+ presenter.onEditProfileClicked();
+ break;
default:
break;
}
diff --git a/ring-android/app/src/main/java/cx/ring/tv/main/MainPresenter.java b/ring-android/app/src/main/java/cx/ring/tv/main/MainPresenter.java
index c63fb9c..1c63f25 100644
--- a/ring-android/app/src/main/java/cx/ring/tv/main/MainPresenter.java
+++ b/ring-android/app/src/main/java/cx/ring/tv/main/MainPresenter.java
@@ -40,6 +40,7 @@
import cx.ring.services.ContactService;
import cx.ring.services.HardwareService;
import cx.ring.services.PresenceService;
+import cx.ring.tv.cards.iconcards.IconCard;
import cx.ring.tv.model.TVContactRequestViewModel;
import cx.ring.tv.model.TVListViewModel;
import cx.ring.utils.Log;
@@ -256,6 +257,14 @@
getView().showExportDialog(mAccountService.getCurrentAccount().getAccountID());
}
+ public void onLicenceClicked(int aboutType) {
+ getView().showLicence(aboutType);
+ }
+
+ public void onEditProfileClicked() {
+ getView().showProfileEditing();
+ }
+
private void subscribePresence() {
if (mAccountService.getCurrentAccount() == null) {
return;
diff --git a/ring-android/app/src/main/java/cx/ring/tv/main/MainView.java b/ring-android/app/src/main/java/cx/ring/tv/main/MainView.java
index 43f0888..f09b3b7 100644
--- a/ring-android/app/src/main/java/cx/ring/tv/main/MainView.java
+++ b/ring-android/app/src/main/java/cx/ring/tv/main/MainView.java
@@ -44,4 +44,8 @@
void displayAccountInfos(String address, RingNavigationViewModel viewModel);
void showExportDialog(String pAccountID);
+
+ void showProfileEditing();
+
+ void showLicence(int aboutType);
}
diff --git a/ring-android/app/src/main/java/cx/ring/tv/views/CustomTitleView.java b/ring-android/app/src/main/java/cx/ring/tv/views/CustomTitleView.java
index 601b824..56c3d5d 100644
--- a/ring-android/app/src/main/java/cx/ring/tv/views/CustomTitleView.java
+++ b/ring-android/app/src/main/java/cx/ring/tv/views/CustomTitleView.java
@@ -31,6 +31,7 @@
* Custom title view to be used in {@link android.support.v17.leanback.app.BrowseFragment}.
*/
public class CustomTitleView extends RelativeLayout implements TitleViewAdapter.Provider {
+ private final TextView mAliasView;
private final TextView mTitleView;
private final ImageView mLogoView;
private final View mSearchOrbView;
@@ -76,6 +77,7 @@
public CustomTitleView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
View root = LayoutInflater.from(context).inflate(R.layout.tv_titleview, this);
+ mAliasView = root.findViewById(R.id.account_alias);
mTitleView = root.findViewById(R.id.title_text);
mLogoView = root.findViewById(R.id.title_photo_contact);
mSearchOrbView = root.findViewById(R.id.title_orb);
@@ -92,6 +94,13 @@
}
}
+ public void setAlias(CharSequence alias) {
+ if (alias != null) {
+ mAliasView.setText(alias);
+ mAliasView.setVisibility(VISIBLE);
+ }
+ }
+
public void setCurrentAccountPhoto(byte[] photo) {
if (photo != null && photo.length > 0) {
Glide.with(getContext())
diff --git a/ring-android/app/src/main/res/drawable/ic_account_card_details_white.xml b/ring-android/app/src/main/res/drawable/ic_account_card_details_white.xml
new file mode 100644
index 0000000..1519e77
--- /dev/null
+++ b/ring-android/app/src/main/res/drawable/ic_account_card_details_white.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportHeight="24"
+ android:viewportWidth="24">
+ <path
+ android:fillColor="#ffffff"
+ android:pathData="M2,3H22C23.05,3 24,3.95 24,5V19C24,20.05 23.05,21 22,21H2C0.95,21 0,20.05 0,19V5C0,3.95 0.95,3 2,3M14,6V7H22V6H14M14,8V9H21.5L22,9V8H14M14,10V11H21V10H14M8,13.91C6,13.91 2,15 2,17V18H14V17C14,15 10,13.91 8,13.91M8,6A3,3 0 0,0 5,9A3,3 0 0,0 8,12A3,3 0 0,0 11,9A3,3 0 0,0 8,6Z" />
+</vector>
\ No newline at end of file
diff --git a/ring-android/app/src/main/res/drawable/ic_group_white.xml b/ring-android/app/src/main/res/drawable/ic_group_white.xml
new file mode 100644
index 0000000..45d435c
--- /dev/null
+++ b/ring-android/app/src/main/res/drawable/ic_group_white.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:pathData="M16,11c1.66,0 2.99,-1.34 2.99,-3S17.66,5 16,5c-1.66,0 -3,1.34 -3,3s1.34,3 3,3zM8,11c1.66,0 2.99,-1.34 2.99,-3S9.66,5 8,5C6.34,5 5,6.34 5,8s1.34,3 3,3zM8,13c-2.33,0 -7,1.17 -7,3.5L1,19h14v-2.5c0,-2.33 -4.67,-3.5 -7,-3.5zM16,13c-0.29,0 -0.62,0.02 -0.97,0.05 1.16,0.84 1.97,1.97 1.97,3.45L17,19h6v-2.5c0,-2.33 -4.67,-3.5 -7,-3.5z"
+ android:fillColor="#FFFFFF"/>
+</vector>
diff --git a/ring-android/app/src/main/res/layout-w960dp-land/tv_activity_profile_editing.xml b/ring-android/app/src/main/res/layout-w960dp-land/tv_activity_profile_editing.xml
new file mode 100644
index 0000000..d914fce
--- /dev/null
+++ b/ring-android/app/src/main/res/layout-w960dp-land/tv_activity_profile_editing.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+Copyright (C) 2004-2018 Savoir-faire Linux Inc.
+
+Author: Adrien Beraud <adrien.beraud@savoirfairelinux.com>
+Pierre Duchemin <pierre.duchemin@savoirfairelinux.com>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+-->
+
+<fragment xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/details_fragment"
+ android:name="cx.ring.tv.account.TVProfileEditingFragment"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:tag="tv_profile_editing" />
\ No newline at end of file
diff --git a/ring-android/app/src/main/res/layout/tv_titleview.xml b/ring-android/app/src/main/res/layout/tv_titleview.xml
index 940a288..10ea79e 100644
--- a/ring-android/app/src/main/res/layout/tv_titleview.xml
+++ b/ring-android/app/src/main/res/layout/tv_titleview.xml
@@ -1,32 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
+<merge xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools">
<android.support.v17.leanback.widget.SearchOrbView
android:id="@+id/title_orb"
- android:layout_height="wrap_content"
android:layout_width="wrap_content"
- android:transitionGroup="true"
+ android:layout_height="wrap_content"
android:layout_gravity="center_vertical|start"
+ android:layout_marginStart="48dp"
android:layout_marginTop="8dp"
- android:layout_marginStart="48dp" />
+ android:transitionGroup="true" />
- <TextView
- android:id="@+id/title_text"
- android:textAppearance="@android:style/TextAppearance.Large"
- android:visibility="gone"
+ <LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginEnd="24dp"
android:layout_centerVertical="true"
- android:layout_toStartOf="@id/title_photo_contact" />
+ android:layout_marginEnd="24dp"
+ android:layout_marginStart="260dp"
+ android:layout_toStartOf="@id/title_photo_contact"
+ android:gravity="end"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/account_alias"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:ellipsize="end"
+ android:maxLines="1"
+ android:textAppearance="@android:style/TextAppearance.Large"
+ android:visibility="gone"
+ tools:text="account alias"
+ tools:visibility="visible" />
+
+ <TextView
+ android:id="@+id/title_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:ellipsize="end"
+ android:maxLines="1"
+ android:textAppearance="@android:style/TextAppearance.DeviceDefault"
+ android:visibility="gone"
+ tools:text="account name"
+ tools:visibility="visible" />
+
+ </LinearLayout>
<ImageView
android:id="@+id/title_photo_contact"
android:layout_width="80dp"
android:layout_height="80dp"
- android:padding="6dp"
- android:src="@drawable/ic_contact_picture"
android:layout_alignParentEnd="true"
android:layout_gravity="center_vertical|end"
- android:layout_marginEnd="24dp" />
+ android:layout_marginEnd="24dp"
+ android:padding="6dp"
+ android:src="@drawable/ic_contact_picture" />
</merge>
\ No newline at end of file
diff --git a/ring-android/app/src/main/res/values-fr-rFR/strings.xml b/ring-android/app/src/main/res/values-fr-rFR/strings.xml
index d714827..9dcf2a2 100644
--- a/ring-android/app/src/main/res/values-fr-rFR/strings.xml
+++ b/ring-android/app/src/main/res/values-fr-rFR/strings.xml
@@ -6,7 +6,7 @@
<string name="contribute_section">Contribuer</string>
<string name="version_section">Version</string>
<string name="no_email_app_installed">Aucun logiciel de messagerie n\'a été trouvé, merci d\'installer un logiciel de messagerie pour nous envoyer un rapport</string>
- <string name="email_chooser_title">Envoyer un courriel en utilisant...</string>
+ <string name="email_chooser_title">Envoyer un courriel en utilisant…</string>
<!--About dialog-->
<!--RingActivity-->
<string name="title_activity_sflphone_home">Ring</string>
@@ -21,9 +21,10 @@
<!--Sections-->
<string name="menu_item_home">Accueil</string>
<string name="menu_item_accounts">Gérer des comptes</string>
+ <string name="menu_item_account">Gérer mon compte</string>
<string name="menu_item_settings">Réglages</string>
<string name="menu_item_share">Partager mes contacts</string>
- <string name="menu_item_about">A propos de Ring</string>
+ <string name="menu_item_about">À propos de Ring</string>
<!--Dialing Fragment-->
<string name="dial_number">Composer un numéro </string>
<!--History Fragment-->
diff --git a/ring-android/app/src/main/res/values/strings.xml b/ring-android/app/src/main/res/values/strings.xml
index 17b579d..b9c2571 100644
--- a/ring-android/app/src/main/res/values/strings.xml
+++ b/ring-android/app/src/main/res/values/strings.xml
@@ -48,7 +48,7 @@
<!-- About dialog -->
<string name="developed_by">Developed by</string>
<string name="designed_by">Designed by</string>
- <string name="credits_developer" translatable="false">Adrien Béraud\nAlexandr Sergheev\nAlexandre Lision\nAlexandre Viau\nAline Bonnet\nAndreas Traczyk\nAnthony Léonard\nCyrille Béraud\nEdric Milaret\nÉloi Bail\nEmmanuel Lepage-Vallée\nFrédéric Guimont\nGuillaume Roguez\nHadrien De Sousa\nJulien Grossholtz\nKateryna Kostiuk\nLoïc Siret\nMarianne Forget\nMichel Schmit\nNicolas Jäger\nNicolas Reynaud\nOlivier Gregoire\nOlivier Soldano\nPatrick Keroulas\nPhilippe Gorley\nRomain Bertozzi\nSaher Azer\nSébastien Blin\nSeva Ivanov\nSilbino Gonçalves Matado\nSimon Désaulniers\nStepan Salenikovich\nSimon Zeni\nThibault Wittemberg</string>
+ <string name="credits_developer" translatable="false">Adrien Béraud\nAlexandr Sergheev\nAlexandre Lision\nAlexandre Viau\nAline Bonnet\nAndreas Traczyk\nAnthony Léonard\nCyrille Béraud\nEdric Milaret\nÉloi Bail\nEmmanuel Lepage-Vallée\nFrédéric Guimont\nGuillaume Roguez\nHadrien De Sousa\nJulien Grossholtz\nKateryna Kostiuk\nLoïc Siret\nMarianne Forget\nMichel Schmit\nNicolas Jäger\nNicolas Reynaud\nOlivier Gregoire\nOlivier Soldano\nPatrick Keroulas\nPierre Duchemin\nPhilippe Gorley\nRomain Bertozzi\nSaher Azer\nSébastien Blin\nSeva Ivanov\nSilbino Gonçalves Matado\nSimon Désaulniers\nStepan Salenikovich\nSimon Zeni\nThibault Wittemberg</string>
<!-- RingActivity -->
<string name="title_activity_sflphone_home">Ring</string>
@@ -66,6 +66,7 @@
<string name="menu_item_home">Home</string>
<string name="menu_item_contact_request">Contact requests</string>
<string name="menu_item_accounts">Manage accounts</string>
+ <string name="menu_item_account">Manage account</string>
<string name="menu_item_settings">Settings</string>
<string name="menu_item_share">Share my contact</string>
<string name="menu_item_about">About Ring</string>
diff --git a/ring-android/app/src/main/res/values/strings_account.xml b/ring-android/app/src/main/res/values/strings_account.xml
index 3cac302..8a1a81a 100644
--- a/ring-android/app/src/main/res/values/strings_account.xml
+++ b/ring-android/app/src/main/res/values/strings_account.xml
@@ -214,6 +214,9 @@
<string name="account_link_title">Link this device</string>
<string name="account_sip_cannot_be_registered">Can\'t register account</string>
+ <!-- Edit profile-->
+ <string name="account_edit_profile">Edit your profile</string>
+
<!-- Devices -->
<string name="account_revoke_device_hint">Enter password to confirm</string>
<string name="enter_password">Enter password</string>
diff --git a/ring-android/libringclient/src/main/java/cx/ring/navigation/RingNavigationPresenter.java b/ring-android/libringclient/src/main/java/cx/ring/navigation/RingNavigationPresenter.java
index a4f6de6..9098a37 100644
--- a/ring-android/libringclient/src/main/java/cx/ring/navigation/RingNavigationPresenter.java
+++ b/ring-android/libringclient/src/main/java/cx/ring/navigation/RingNavigationPresenter.java
@@ -83,13 +83,12 @@
mAccountService.setCurrentAccount(selectedAccount);
}
- public void saveVCard(String username, Photo photo) {
+ public void saveVCardPhoto(Photo photo) {
String accountId = mAccountService.getCurrentAccount().getAccountID();
String ringId = mAccountService.getCurrentAccount().getUsername();
File filesDir = mDeviceRuntimeService.provideFilesDir();
VCard vcard = VCardUtils.loadLocalProfileFromDisk(filesDir, accountId);
- vcard.setFormattedName(username);
vcard.setUid(new Uid(ringId));
vcard.removeProperties(Photo.class);
vcard.addPhoto(photo);
@@ -99,7 +98,7 @@
updateUser();
}
- public void saveVCard(String username) {
+ public void saveVCardFormattedName(String username) {
String accountId = mAccountService.getCurrentAccount().getAccountID();
File filesDir = mDeviceRuntimeService.provideFilesDir();