Bug 942281 - Add a view for authentication UI to DynamicPanel (r=lucasr)

This commit is contained in:
Margaret Leibovic 2014-03-27 09:25:04 -07:00
parent e804983f2c
commit 55e4fb900f
7 changed files with 197 additions and 3 deletions

View File

@ -31,6 +31,7 @@ import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
/**
* Fragment that displays dynamic content specified by a {@code PanelConfig}.
@ -58,9 +59,15 @@ public class DynamicPanel extends HomeFragment
// Dataset ID to be used by the loader
private static final String DATASET_REQUEST = "dataset_request";
// The main view for this fragment. This contains the PanelLayout and PanelAuthLayout.
private FrameLayout mView;
// The panel layout associated with this panel
private PanelLayout mPanelLayout;
// The layout used to show authentication UI for this panel
private PanelAuthLayout mPanelAuthLayout;
// The configuration associated with this panel
private PanelConfig mPanelConfig;
@ -117,7 +124,10 @@ public class DynamicPanel extends HomeFragment
Log.d(LOGTAG, "Created layout of type: " + mPanelConfig.getLayoutType());
return mPanelLayout;
mView = new FrameLayout(getActivity());
mView.addView(mPanelLayout);
return mView;
}
@Override
@ -129,7 +139,9 @@ public class DynamicPanel extends HomeFragment
@Override
public void onDestroyView() {
super.onDestroyView();
mView = null;
mPanelLayout = null;
mPanelAuthLayout = null;
GeckoAppShell.unregisterEventListener("HomePanels:RefreshDataset", this);
}
@ -159,7 +171,31 @@ public class DynamicPanel extends HomeFragment
@Override
protected void load() {
Log.d(LOGTAG, "Loading layout");
mPanelLayout.load();
if (requiresAuth()) {
// TODO: check to see if the panel isn't already authenticated
setAuthVisible(true);
} else {
mPanelLayout.load();
}
}
/**
* @return true if this panel requires authentication.
*/
private boolean requiresAuth() {
return mPanelConfig.getAuthConfig() != null;
}
private void setAuthVisible(boolean visible) {
// Lazily create PanelAuthLayout.
if (visible && mPanelAuthLayout == null) {
mPanelAuthLayout = new PanelAuthLayout(getActivity(), mPanelConfig);
mView.addView(mPanelAuthLayout, 0);
}
mPanelAuthLayout.setVisibility(visible ? View.VISIBLE : View.GONE);
mPanelLayout.setVisibility(visible ? View.GONE : View.VISIBLE);
}
@Override

View File

@ -0,0 +1,64 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.home;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.GeckoEvent;
import org.mozilla.gecko.R;
import org.mozilla.gecko.home.HomeConfig.AuthConfig;
import org.mozilla.gecko.home.HomeConfig.PanelConfig;
import android.content.Context;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
class PanelAuthLayout extends LinearLayout {
public PanelAuthLayout(Context context, PanelConfig panelConfig) {
super(context);
final AuthConfig authConfig = panelConfig.getAuthConfig();
if (authConfig == null) {
throw new IllegalStateException("Can't create PanelAuthLayout without a valid AuthConfig");
}
setOrientation(LinearLayout.VERTICAL);
LayoutInflater.from(context).inflate(R.layout.panel_auth_layout, this);
final TextView messageView = (TextView) findViewById(R.id.message);
messageView.setText(authConfig.getMessageText());
final Button buttonView = (Button) findViewById(R.id.button);
buttonView.setText(authConfig.getButtonText());
final String panelId = panelConfig.getId();
buttonView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("HomePanels:Authenticate", panelId));
}
});
final ImageView imageView = (ImageView) findViewById(R.id.image);
final String imageUrl = authConfig.getImageUrl();
if (TextUtils.isEmpty(imageUrl)) {
// Use a default image if an image URL isn't specified.
imageView.setImageResource(R.drawable.icon_home_empty_firefox);
} else {
Picasso.with(getContext())
.load(imageUrl)
.into(imageView);
}
}
}

View File

@ -248,6 +248,7 @@ gbjar.sources += [
'home/LastTabsPanel.java',
'home/MostRecentPanel.java',
'home/MultiTypeCursorAdapter.java',
'home/PanelAuthLayout.java',
'home/PanelBackItemView.java',
'home/PanelGridView.java',
'home/PanelItemView.java',

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<layer-list>
<item android:left="-2dp"
android:right="-2dp"
android:top="-2dp">
<shape android:shape="rectangle" >
<stroke android:width="2dp"
android:color="#FFE0E4E7" />
<solid android:color="#FFC5D0DA" />
</shape>
</item>
</layer-list>
</item>
<item>
<layer-list>
<item android:left="-2dp"
android:right="-2dp"
android:top="-2dp">
<shape android:shape="rectangle" >
<stroke android:width="2dp"
android:color="#FFE0E4E7" />
<solid android:color="@color/background_light" />
</shape>
</item>
</layer-list>
</item>
</selector>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Empty spacer view -->
<View android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1"/>
<ImageView android:id="@+id/image"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="top|center"
android:scaleType="center"
android:paddingBottom="10dp"/>
<TextView android:id="@+id/message"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:gravity="top|center"
android:textAppearance="@style/TextAppearance.EmptyMessage"
android:paddingLeft="50dp"
android:paddingRight="50dp"
android:layout_weight="3"/>
<Button android:id="@+id/button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="25dp"
android:layout_marginRight="25dp"
android:layout_marginBottom="25dp"
android:gravity="bottom|center"
android:textAppearance="@style/TextAppearance.EmptyMessage"
android:background="@drawable/panel_auth_button"
android:padding="20dp"/>
</merge>

View File

@ -131,7 +131,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "CharsetMenu",
// Lazily-loaded JS modules that use observer notifications
[
["Home", ["HomePanels:Get"], "resource://gre/modules/Home.jsm"],
["Home", ["HomePanels:Get", "HomePanels:Authenticate"], "resource://gre/modules/Home.jsm"],
].forEach(module => {
let [name, notifications, resource] = module;
XPCOMUtils.defineLazyModuleGetter(this, name, resource);

View File

@ -157,6 +157,7 @@ let HomeBanner = (function () {
// We need this function to have access to the HomePanels
// private members without leaking it outside Home.jsm.
let handlePanelsGet;
let handlePanelsAuthenticate;
let HomePanels = (function () {
// Holds the current set of registered panels that can be
@ -284,6 +285,18 @@ let HomePanels = (function () {
});
};
handlePanelsAuthenticate = function(id) {
// Generate panel options to get auth handler.
let options = _registeredPanels[id]();
if (!options.authHandler) {
throw "Home.panels: Invalid authHandler for panel.id = " + id;
}
if (!options.authHandler.authenticate || typeof options.authHandler.authenticate !== "function") {
throw "Home.panels: Invalid authHandler authenticate function: panel.id = " + this.id;
}
options.authHandler.authenticate();
};
// Helper function used to see if a value is in an object.
let _valueExists = function(obj, value) {
for (let key in obj) {
@ -365,6 +378,9 @@ this.Home = Object.freeze({
case "HomePanels:Get":
handlePanelsGet(JSON.parse(data));
break;
case "HomePanels:Authenticate":
handlePanelsAuthenticate(data);
break;
}
}
});