Skip to content
Snippets Groups Projects
Commit bae38f53 authored by Aline Bonnet's avatar Aline Bonnet
Browse files

mvp: refactor AccountsManagementFragment


This commit applies MVP to AccountsManagementFragment

Change-Id: I56e1e3658f41b581feccad3ff8026b56bf7baab2
Reviewed-by: default avatarHadrien De Sousa <hadrien.desousa@savoirfairelinux.com>
Tuleap: #1366
parent 5f420e2b
No related branches found
No related tags found
No related merge requests found
/*
* Copyright (C) 2017 Savoir-faire Linux Inc.
*
* Author: Aline Bonnet <aline.bonnet@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.account;
import android.graphics.Color;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import cx.ring.R;
import cx.ring.model.Account;
import cx.ring.model.ConfigKey;
public class AccountsAdapter extends BaseAdapter {
static final String TAG = AccountsAdapter.class.getSimpleName();
private final ArrayList<Account> accounts = new ArrayList<>();
private AccountListeners mListeners;
public AccountsAdapter(AccountListeners listeners) {
mListeners = listeners;
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public int getCount() {
return accounts.size();
}
@Override
public Account getItem(int pos) {
return accounts.get(pos);
}
@Override
public long getItemId(int pos) {
return 0;
}
@Override
public View getView(final int pos, View convertView, ViewGroup parent) {
View rowView = convertView;
AccountView entryView;
if (rowView == null) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
rowView = inflater.inflate(R.layout.item_account_pref, parent, false);
entryView = new AccountView();
entryView.alias = (TextView) rowView.findViewById(R.id.account_alias);
entryView.host = (TextView) rowView.findViewById(R.id.account_host);
entryView.loadingIndicator = rowView.findViewById(R.id.loading_indicator);
entryView.errorIndicator = (ImageView) rowView.findViewById(R.id.error_indicator);
entryView.enabled = (CheckBox) rowView.findViewById(R.id.account_checked);
entryView.errorIndicator.setColorFilter(parent.getContext().getResources().getColor(R.color.error_red));
entryView.errorIndicator.setVisibility(View.GONE);
entryView.loadingIndicator.setVisibility(View.GONE);
rowView.setTag(entryView);
} else {
entryView = (AccountView) rowView.getTag();
}
final Account item = accounts.get(pos);
entryView.alias.setText(item.getAlias());
entryView.host.setTextColor(ContextCompat.getColor(parent.getContext(), R.color.text_color_secondary));
if (item.isIP2IP()) {
entryView.host.setText(item.getRegistrationState());
} else if (item.isSip()) {
entryView.host.setText(item.getHost() + " - " + item.getRegistrationState());
} else {
entryView.host.setText(item.getDetail(ConfigKey.ACCOUNT_USERNAME));
}
entryView.enabled.setChecked(item.isEnabled());
entryView.enabled.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
item.setEnabled(!item.isEnabled());
mListeners.onItemClicked(item.getAccountID(), item.getDetails());
}
});
if (item.isEnabled()) {
if (item.isTrying()) {
entryView.errorIndicator.setVisibility(View.GONE);
entryView.loadingIndicator.setVisibility(View.VISIBLE);
} else if (item.needsMigration()) {
entryView.host.setText(R.string.account_update_needed);
entryView.host.setTextColor(Color.RED);
entryView.errorIndicator.setImageResource(R.drawable.ic_warning);
entryView.errorIndicator.setColorFilter(Color.RED);
entryView.errorIndicator.setVisibility(View.VISIBLE);
} else if (item.isInError()) {
entryView.errorIndicator.setImageResource(R.drawable.ic_error_white);
entryView.errorIndicator.setColorFilter(Color.RED);
entryView.errorIndicator.setVisibility(View.VISIBLE);
entryView.loadingIndicator.setVisibility(View.GONE);
} else if (!item.isRegistered()) {
entryView.errorIndicator.setImageResource(R.drawable.ic_network_disconnect_black_24dp);
entryView.errorIndicator.setColorFilter(Color.BLACK);
entryView.errorIndicator.setVisibility(View.VISIBLE);
entryView.loadingIndicator.setVisibility(View.GONE);
} else {
entryView.errorIndicator.setVisibility(View.GONE);
entryView.loadingIndicator.setVisibility(View.GONE);
}
} else {
entryView.errorIndicator.setVisibility(View.GONE);
entryView.loadingIndicator.setVisibility(View.GONE);
}
return rowView;
}
/**
* ******************
* ViewHolder Pattern
* *******************
*/
public class AccountView {
public TextView alias;
public TextView host;
public View loadingIndicator;
public ImageView errorIndicator;
public CheckBox enabled;
}
public void replaceAll(List<Account> results) {
Log.d(TAG, "AccountsAdapter replaceAll " + results.size());
accounts.clear();
accounts.addAll(results);
notifyDataSetChanged();
}
public interface AccountListeners {
void onItemClicked(String accountId, HashMap<String, String> details);
}
}
......@@ -22,10 +22,7 @@
package cx.ring.fragments;
import android.app.Fragment;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
......@@ -36,44 +33,34 @@ import android.view.MenuInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import javax.inject.Inject;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnItemClick;
import cx.ring.R;
import cx.ring.account.AccountsAdapter;
import cx.ring.account.AccountsManagementPresenter;
import cx.ring.account.AccountsManagementView;
import cx.ring.application.RingApplication;
import cx.ring.account.AccountEditionActivity;
import cx.ring.client.AccountWizard;
import cx.ring.client.HomeActivity;
import cx.ring.model.Account;
import cx.ring.model.ConfigKey;
import cx.ring.model.ServiceEvent;
import cx.ring.services.AccountService;
import cx.ring.mvp.BaseFragment;
import cx.ring.utils.ContentUriHandler;
import cx.ring.utils.Observable;
import cx.ring.utils.Observer;
public class AccountsManagementFragment extends Fragment implements HomeActivity.Refreshable, Observer<ServiceEvent> {
public class AccountsManagementFragment extends BaseFragment<AccountsManagementPresenter> implements AccountsManagementView,
AccountsAdapter.AccountListeners {
static final String TAG = AccountsManagementFragment.class.getSimpleName();
public static final int ACCOUNT_CREATE_REQUEST = 1;
public static final int ACCOUNT_EDIT_REQUEST = 2;
private AccountsAdapter mAccountsAdapter;
@Inject
AccountService mAccountService;
@BindView(R.id.accounts_list)
ListView mDnDListView;
......@@ -88,7 +75,7 @@ public class AccountsManagementFragment extends Fragment implements HomeActivity
// dependency injection
((RingApplication) getActivity().getApplication()).getRingInjectionComponent().inject(this);
mAccountsAdapter = new AccountsAdapter(getActivity());
mAccountsAdapter = new AccountsAdapter(this);
}
@Override
......@@ -108,34 +95,20 @@ public class AccountsManagementFragment extends Fragment implements HomeActivity
@OnItemClick(R.id.accounts_list)
@SuppressWarnings("unused")
void onItemClick(AdapterView<?> arg0, View arg1, int pos, long arg3) {
Account selectedAccount = mAccountsAdapter.getItem(pos);
if (selectedAccount.needsMigration()) {
launchAccountMigrationActivity(mAccountsAdapter.getItem(pos));
} else {
launchAccountEditActivity(mAccountsAdapter.getItem(pos));
}
}
@Override
public void onPause() {
super.onPause();
mAccountService.removeObserver(this);
void onItemClick(int pos) {
presenter.clickAccount(mAccountsAdapter.getItem(pos));
}
@Override
public void onResume() {
super.onResume();
mAccountService.addObserver(this);
refresh();
((HomeActivity) getActivity()).setToolbarState(true, R.string.menu_item_accounts);
FloatingActionButton btn = ((HomeActivity) getActivity()).getActionButton();
btn.setImageResource(R.drawable.ic_add_white);
btn.setOnClickListener(new OnClickListener() {
FloatingActionButton button = ((HomeActivity) getActivity()).getActionButton();
button.setImageResource(R.drawable.ic_add_white);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), AccountWizard.class);
startActivityForResult(intent, ACCOUNT_CREATE_REQUEST);
presenter.addClicked();
}
});
}
......@@ -150,192 +123,54 @@ public class AccountsManagementFragment extends Fragment implements HomeActivity
menu.clear();
}
private void launchAccountEditActivity(Account acc) {
@Override
public void launchAccountEditActivity(Account account) {
Log.d(TAG, "Launch account edit activity");
Intent intent = new Intent(getActivity(), AccountEditionActivity.class)
.setAction(Intent.ACTION_EDIT)
.setData(Uri.withAppendedPath(ContentUriHandler.ACCOUNTS_CONTENT_URI, acc.getAccountID()));
.setData(Uri.withAppendedPath(ContentUriHandler.ACCOUNTS_CONTENT_URI, account.getAccountID()));
startActivityForResult(intent, ACCOUNT_EDIT_REQUEST);
}
private void launchAccountMigrationActivity(Account acc) {
@Override
public void launchAccountMigrationActivity(Account account) {
Log.d(TAG, "Launch account migration activity");
Intent intent = new Intent()
.setClass(getActivity(), AccountWizard.class)
.setData(Uri.withAppendedPath(ContentUriHandler.ACCOUNTS_CONTENT_URI, acc.getAccountID()));
.setData(Uri.withAppendedPath(ContentUriHandler.ACCOUNTS_CONTENT_URI, account.getAccountID()));
startActivityForResult(intent, ACCOUNT_EDIT_REQUEST);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
refresh();
public void launchWizardActivity() {
Intent intent = new Intent(getActivity(), AccountWizard.class);
startActivityForResult(intent, ACCOUNT_CREATE_REQUEST);
}
@Override
public void update(Observable observable, ServiceEvent event) {
if (event == null) {
return;
}
switch (event.getEventType()) {
case ACCOUNTS_CHANGED:
case REGISTRATION_STATE_CHANGED:
RingApplication.uiHandler.post(new Runnable() {
@Override
public void run() {
refresh();
}
});
break;
default:
Log.d(TAG, "This event is not handled here");
break;
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
presenter.refresh();
}
/**
* Adapter for accounts List
*
* @author lisional
*/
public class AccountsAdapter extends BaseAdapter {
private final ArrayList<Account> accounts = new ArrayList<>();
private final Context mContext;
public AccountsAdapter(Context c) {
super();
mContext = c;
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public int getCount() {
return accounts.size();
}
@Override
public Account getItem(int pos) {
return accounts.get(pos);
}
@Override
public long getItemId(int pos) {
return 0;
}
@Override
public View getView(final int pos, View convertView, ViewGroup parent) {
View rowView = convertView;
AccountView entryView;
if (rowView == null) {
LayoutInflater inflater = LayoutInflater.from(mContext);
rowView = inflater.inflate(R.layout.item_account_pref, parent, false);
entryView = new AccountView();
entryView.alias = (TextView) rowView.findViewById(R.id.account_alias);
entryView.host = (TextView) rowView.findViewById(R.id.account_host);
entryView.loadingIndicator = rowView.findViewById(R.id.loading_indicator);
entryView.errorIndicator = (ImageView) rowView.findViewById(R.id.error_indicator);
entryView.enabled = (CheckBox) rowView.findViewById(R.id.account_checked);
entryView.errorIndicator.setColorFilter(mContext.getResources().getColor(R.color.error_red));
entryView.errorIndicator.setVisibility(View.GONE);
entryView.loadingIndicator.setVisibility(View.GONE);
rowView.setTag(entryView);
} else {
entryView = (AccountView) rowView.getTag();
}
final Account item = accounts.get(pos);
entryView.alias.setText(item.getAlias());
entryView.host.setTextColor(getResources().getColor(R.color.text_color_secondary));
if (item.isIP2IP()) {
entryView.host.setText(item.getRegistrationState());
} else if (item.isSip()) {
entryView.host.setText(item.getHost() + " - " + item.getRegistrationState());
} else {
entryView.host.setText(item.getDetail(ConfigKey.ACCOUNT_USERNAME));
}
entryView.enabled.setChecked(item.isEnabled());
entryView.enabled.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
item.setEnabled(!item.isEnabled());
mAccountService.setAccountDetails(item.getAccountID(), item.getDetails());
}
});
if (item.isEnabled()) {
if (item.isTrying()) {
entryView.errorIndicator.setVisibility(View.GONE);
entryView.loadingIndicator.setVisibility(View.VISIBLE);
} else if (item.needsMigration()) {
entryView.host.setText(R.string.account_update_needed);
entryView.host.setTextColor(Color.RED);
entryView.errorIndicator.setImageResource(R.drawable.ic_warning);
entryView.errorIndicator.setColorFilter(Color.RED);
entryView.errorIndicator.setVisibility(View.VISIBLE);
} else if (item.isInError()) {
entryView.errorIndicator.setImageResource(R.drawable.ic_error_white);
entryView.errorIndicator.setColorFilter(Color.RED);
entryView.errorIndicator.setVisibility(View.VISIBLE);
entryView.loadingIndicator.setVisibility(View.GONE);
} else if (!item.isRegistered()) {
entryView.errorIndicator.setImageResource(R.drawable.ic_network_disconnect_black_24dp);
entryView.errorIndicator.setColorFilter(Color.BLACK);
entryView.errorIndicator.setVisibility(View.VISIBLE);
entryView.loadingIndicator.setVisibility(View.GONE);
} else {
entryView.errorIndicator.setVisibility(View.GONE);
entryView.loadingIndicator.setVisibility(View.GONE);
@Override
public void refresh(final List<Account> accounts) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
mAccountsAdapter.replaceAll(accounts);
if (mAccountsAdapter.isEmpty() && mDnDListView != null) {
mDnDListView.setEmptyView(mEmptyView);
}
} else {
entryView.errorIndicator.setVisibility(View.GONE);
entryView.loadingIndicator.setVisibility(View.GONE);
mAccountsAdapter.notifyDataSetChanged();
}
return rowView;
}
/**
* ******************
* ViewHolder Pattern
* *******************
*/
public class AccountView {
public TextView alias;
public TextView host;
public View loadingIndicator;
public ImageView errorIndicator;
public CheckBox enabled;
}
public void replaceAll(List<Account> results) {
Log.d(TAG, "AccountsAdapter replaceAll " + results.size());
accounts.clear();
accounts.addAll(results);
notifyDataSetChanged();
}
});
}
@Override
public void refresh() {
mAccountsAdapter.replaceAll(mAccountService.getAccounts());
if (mAccountsAdapter.isEmpty() && mDnDListView != null) {
mDnDListView.setEmptyView(mEmptyView);
}
mAccountsAdapter.notifyDataSetChanged();
public void onItemClicked(String accountId, HashMap<String, String> details) {
presenter.itemClicked(accountId, details);
}
}
/*
* Copyright (C) 2017 Savoir-faire Linux Inc.
*
* Author: Aline Bonnet <aline.bonnet@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.account;
import java.util.Map;
import javax.inject.Inject;
import cx.ring.model.Account;
import cx.ring.model.ServiceEvent;
import cx.ring.mvp.RootPresenter;
import cx.ring.services.AccountService;
import cx.ring.utils.Log;
import cx.ring.utils.Observable;
import cx.ring.utils.Observer;
public class AccountsManagementPresenter extends RootPresenter<AccountsManagementView> implements Observer<ServiceEvent> {
private static final String TAG = AccountsManagementPresenter.class.getSimpleName();
private AccountService mAccountService;
@Inject
public AccountsManagementPresenter(AccountService accountService) {
mAccountService = accountService;
}
@Override
public void afterInjection() {
}
@Override
public void bindView(AccountsManagementView view) {
super.bindView(view);
mAccountService.addObserver(this);
view.refresh(mAccountService.getAccounts());
}
@Override
public void unbindView() {
super.unbindView();
mAccountService.removeObserver(this);
}
public void clickAccount(Account account) {
if (account.needsMigration()) {
getView().launchAccountMigrationActivity(account);
} else {
getView().launchAccountEditActivity(account);
}
}
public void refresh() {
getView().refresh(mAccountService.getAccounts());
}
public void addClicked() {
getView().launchWizardActivity();
}
public void itemClicked(String accountId, Map<String, String> details) {
mAccountService.setAccountDetails(accountId, details);
}
@Override
public void update(Observable observable, ServiceEvent event) {
if (event == null) {
return;
}
switch (event.getEventType()) {
case ACCOUNTS_CHANGED:
case REGISTRATION_STATE_CHANGED:
getView().refresh(mAccountService.getAccounts());
break;
default:
Log.d(TAG, "This event is not handled here");
break;
}
}
}
/*
* Copyright (C) 2017 Savoir-faire Linux Inc.
*
* Author: Aline Bonnet <aline.bonnet@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.account;
import java.util.List;
import cx.ring.model.Account;
public interface AccountsManagementView {
void refresh(List<Account> accounts);
void launchAccountMigrationActivity(Account account);
void launchAccountEditActivity(Account account);
void launchWizardActivity();
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment