Commit a67b71c1 authored by Tina Wang's avatar Tina Wang Committed by Commit Bot

[ProfileCard] Introduce Profile Card structure

- No user visible change in this cl.
- Add new directory for profile card.
- Add basic classes.

Change-Id: Ic09d5f097f712a9c58c1ed666eba22fac1d9236c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1993146Reviewed-by: default avatarsebsg <sebsg@chromium.org>
Reviewed-by: default avatarDavid Trainor <dtrainor@chromium.org>
Commit-Queue: Tina Wang <tinazwang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#732554}
parent b7fceb80
# Copyright 2020 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/config/android/rules.gni")
android_library("java") {
sources = [ "java/src/org/chromium/chrome/browser/profile_card/ProfileCardCoordinator.java" ]
deps = [ "//chrome/lib/lifecycle/public/android:java" ]
}
android_resources("java_resources") {
custom_package = "org.chromium.chrome.browser.profile_card"
resource_dirs = [ "java/res" ]
deps = [ "//ui/android:ui_java_resources" ]
}
# Copyright 2020 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//build/config/android/rules.gni")
android_library("java") {
sources = [
"java/src/org/chromium/chrome/browser/profile_card/ProfileCardCoordinatorImpl.java",
"java/src/org/chromium/chrome/browser/profile_card/ProfileCardMediator.java",
"java/src/org/chromium/chrome/browser/profile_card/ProfileCardProperties.java",
"java/src/org/chromium/chrome/browser/profile_card/ProfileCardView.java",
"java/src/org/chromium/chrome/browser/profile_card/ProfileCardViewBinder.java",
]
deps = [
":java_resources",
"//base:base_java",
]
}
android_resources("java_resources") {
custom_package = "org.chromium.chrome.browser.profile_card.internal"
resource_dirs = [ "java/res" ]
visibility = [ ":*" ]
# Include resource dependencies needed by :java so that resources may
# all be accessed through the same custom_package.
deps = [ "//chrome/browser/profile_card:java_resources" ]
}
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2020 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.Title2.Inverse" />
<TextView
android:id="@+id/description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.Title2.Inverse" />
</LinearLayout>
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.profile_card.internal;
import android.view.View;
import org.json.JSONException;
import org.json.JSONObject;
import org.chromium.base.Log;
import org.chromium.ui.modelutil.PropertyModel;
import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
import org.chromium.ui.widget.ViewRectProvider;
/**
* Implements ProfileCardCoordinator.
* Talks to other components and decides when to show/update the profile card.
*/
public class ProfileCardCoordinatorImpl implements ProfileCardCoordinator {
private static final String TAG = "ShowError";
private final PropertyModel mModel;
private final ProfileCardView mView;
private final ProfileCardMediator mMediator;
private final PropertyModelChangeProcessor mModelChangeProcessor;
private final JSONObject mProfileCardData;
@Override
public void update(View anchorView, JSONObject profileCardData) {
if (mProfileCardData == profileCardData) return;
ViewRectProvider rectProvider = new ViewRectProvider(anchorView);
mView = new ProfileCardView(anchorView.getContext(), anchorView, /*stringId=*/"",
/*accessibilityStringId=*/"", rectProvider);
mProfileCardData = profileCardData;
mModel = new PropertyModel(ProfileCardProperties.ALL_KEYS);
mModelChangeProcessor =
PropertyModelChangeProcessor.create(mModel, mView, ProfileCardViewBinder::bind);
mMediator = new ProfileCardMediator(mModel, profileCardData);
}
@Override
public void show() {
try {
mMediator.show();
} catch (JSONException e) {
e.printStackTrace();
Log.e(TAG, "Failed to show profile card.");
}
}
}
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.profile_card.internal;
import static org.chromium.chrome.features.profile_card.ProfileCardProperties.DESCRIPTION;
import static org.chromium.chrome.features.profile_card.ProfileCardProperties.IS_DIALOG_VISIBLE;
import static org.chromium.chrome.features.profile_card.ProfileCardProperties.TITLE;
import org.json.JSONException;
import org.json.JSONObject;
import org.chromium.ui.modelutil.PropertyModel;
/**
* A mediator for the ProfileCard component, responsible for communicating
* with the components' coordinator.
* Reacts to changes in the backend and updates the model.
* Receives events from the view (callback) and notifies the backend.
*/
class ProfileCardMediator {
private static final String NAME = "name";
private static final String DESCRIPTION_OBJ = "description";
private static final String TEXT = "text";
private final PropertyModel mModel;
private final JSONObject mProfileCardData;
ProfileCardMediator(PropertyModel model, JSONObject profileCardData) {
mModel = model;
mProfileCardData = profileCardData;
}
public void show() throws JSONException {
// Set all properties.
mModel.set(TITLE, mProfileCardData.getString(NAME));
mModel.set(DESCRIPTION, mProfileCardData.getJSONObject(DESCRIPTION_OBJ).getString(TEXT));
mModel.set(IS_DIALOG_VISIBLE, true);
}
}
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.profile_card.internal;
import org.chromium.ui.modelutil.PropertyKey;
import org.chromium.ui.modelutil.PropertyModel;
class ProfileCardProperties extends PropertyModel {
public static final PropertyModel.WritableObjectPropertyKey<String> TITLE =
new PropertyModel.WritableObjectPropertyKey<String>();
public static final PropertyModel.WritableObjectPropertyKey<String> DESCRIPTION =
new PropertyModel.WritableObjectPropertyKey<String>();
public static final PropertyModel.WritableBooleanPropertyKey IS_DIALOG_VISIBLE =
new PropertyModel.WritableBooleanPropertyKey();
public static final PropertyKey[] ALL_KEYS =
new PropertyKey[] {TITLE, DESCRIPTION, IS_DIALOG_VISIBLE};
}
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.profile_card.internal;
import android.content.Context;
import android.text.method.ScrollingMovementMethod;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import org.chromium.chrome.browser.ui.widget.textbubble.TextBubble;
import org.chromium.ui.widget.RectProvider;
/**
* UI component that handles showing a text bubble with a preceding image.
*/
public class ProfileCardView extends TextBubble {
private View mMainContentView;
private TextView mTitleTextView;
private TextView mDescriptionTextView;
private ImageButton mFollowBtn;
private LinearLayout mNetworkContainer;
/**
* Constructs a {@link ProfileCardView} instance.
* @param context Context to draw resources from.
* @param rootView The {@link View} to use for size calculations and for display.
* @param stringId The id of the string resource for the text that should be shown.
* @param accessibilityStringId The id of the string resource of the accessibility text.
* @param anchorRectProvider The {@link RectProvider} used to anchor the text bubble.
*/
public ProfileCardView(Context context, View rootView, String stringId,
String accessibilityStringId, RectProvider anchorRectProvider) {
super(context, rootView, stringId, accessibilityStringId, /*showArrow=*/true,
anchorRectProvider);
setColor(context.getResources().getColor(org.chromium.chrome.R.color.material_grey_100));
setCardDismissListener();
}
@Override
protected View createContentView() {
mMainContentView =
LayoutInflater.from(mContext).inflate(R.layout.profile_card, /*root=*/null);
mTitleTextView = mMainContentView.findViewById(R.id.title);
mDescriptionTextView = mMainContentView.findViewById(R.id.description);
mDescriptionTextView.setMovementMethod(new ScrollingMovementMethod());
return mMainContentView;
}
void setTitle(String title) {
if (mTitleTextView == null) {
throw new IllegalStateException("Current dialog doesn't have a title text view");
}
mTitleTextView.setText(title);
}
void setDescription(String description) {
if (mDescriptionTextView == null) {
throw new IllegalStateException("Current dialog doesn't have a description text view");
}
mDescriptionTextView.setText(description);
}
void setVisibility(boolean visible) {
if (visible) {
setOutsideTouchable(true);
show();
} else {
dismiss();
}
}
void setCardDismissListener() {
addOnDismissListener(new OnDismissListener() {
@Override
public void onDismiss() {
setVisibility(false);
}
});
}
}
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.profile_card.internal;
import static org.chromium.chrome.features.profile_card.ProfileCardProperties.DESCRIPTION;
import static org.chromium.chrome.features.profile_card.ProfileCardProperties.IS_DIALOG_VISIBLE;
import static org.chromium.chrome.features.profile_card.ProfileCardProperties.TITLE;
import org.chromium.ui.modelutil.PropertyKey;
import org.chromium.ui.modelutil.PropertyModel;
class ProfileCardViewBinder {
/*
* Bind the given model to the given view, updating the payload in propertyKey.
* @param model The model to use.
* @param view The View to use.
* @param propertyKey The key for the property to update for.
*/
public static void bind(PropertyModel model, ProfileCardView view, PropertyKey propertyKey) {
if (TITLE == propertyKey) {
view.setTitle(model.get(TITLE));
} else if (DESCRIPTION == propertyKey) {
view.setDescription(model.get(DESCRIPTION));
} else if (IS_DIALOG_VISIBLE == propertyKey) {
view.setVisibility(model.get(IS_DIALOG_VISIBLE));
}
}
}
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.profile_card;
import android.view.View;
import org.json.JSONObject;
/** Interface for the Profile Card related UI. */
public interface ProfileCardCoordinator {
/**
* Updates the {@link ProfileCard}
* @param view {@link View} triggers the profile card.
* @param profileCardData {@link JSONObject} stores all data needed by profile card.
*/
void update(View view, JSONObject profileCardData);
/**
* Shows the profile card drop-down bubble.
*/
void show();
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment