DrawerActivity.java 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849
  1. /**
  2. * Nextcloud Android client application
  3. *
  4. * @author Andy Scherzinger
  5. * Copyright (C) 2016 Andy Scherzinger
  6. * Copyright (C) 2016 Nextcloud
  7. * Copyright (C) 2016 ownCloud Inc.
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
  11. * License as published by the Free Software Foundation; either
  12. * version 3 of the License, or any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
  18. *
  19. * You should have received a copy of the GNU Affero General Public
  20. * License along with this program. If not, see <http://www.gnu.org/licenses/>.
  21. */
  22. package com.owncloud.android.ui.activity;
  23. import android.accounts.Account;
  24. import android.accounts.AccountManager;
  25. import android.accounts.AccountManagerFuture;
  26. import android.content.Intent;
  27. import android.content.res.Configuration;
  28. import android.graphics.drawable.Drawable;
  29. import android.os.Build;
  30. import android.os.Bundle;
  31. import android.os.Handler;
  32. import android.support.design.widget.NavigationView;
  33. import android.support.v4.view.GravityCompat;
  34. import android.support.v4.widget.DrawerLayout;
  35. import android.support.v7.app.ActionBarDrawerToggle;
  36. import android.view.Menu;
  37. import android.view.MenuItem;
  38. import android.view.View;
  39. import android.widget.ImageView;
  40. import android.widget.LinearLayout;
  41. import android.widget.ProgressBar;
  42. import android.widget.TextView;
  43. import com.owncloud.android.MainApp;
  44. import com.owncloud.android.R;
  45. import com.owncloud.android.authentication.AccountUtils;
  46. import com.owncloud.android.datamodel.OCFile;
  47. import com.owncloud.android.lib.common.OwnCloudAccount;
  48. import com.owncloud.android.lib.common.Quota;
  49. import com.owncloud.android.lib.common.UserInfo;
  50. import com.owncloud.android.lib.common.operations.RemoteOperation;
  51. import com.owncloud.android.lib.common.operations.RemoteOperationResult;
  52. import com.owncloud.android.lib.common.utils.Log_OC;
  53. import com.owncloud.android.lib.resources.users.GetRemoteUserInfoOperation;
  54. import com.owncloud.android.ui.TextDrawable;
  55. import com.owncloud.android.utils.DisplayUtils;
  56. /**
  57. * Base class to handle setup of the drawer implementation including user switching and avatar fetching and fallback
  58. * generation.
  59. */
  60. public abstract class DrawerActivity extends ToolbarActivity implements DisplayUtils.AvatarGenerationListener {
  61. private static final String TAG = DrawerActivity.class.getSimpleName();
  62. private static final String KEY_IS_ACCOUNT_CHOOSER_ACTIVE = "IS_ACCOUNT_CHOOSER_ACTIVE";
  63. private static final String KEY_CHECKED_MENU_ITEM = "CHECKED_MENU_ITEM";
  64. private static final int ACTION_MANAGE_ACCOUNTS = 101;
  65. private static final int MENU_ORDER_ACCOUNT = 1;
  66. private static final int MENU_ORDER_ACCOUNT_FUNCTION = 2;
  67. /**
  68. * menu account avatar radius.
  69. */
  70. private float mMenuAccountAvatarRadiusDimension;
  71. /**
  72. * current account avatar radius.
  73. */
  74. private float mCurrentAccountAvatarRadiusDimension;
  75. /**
  76. * other accounts avatar radius.
  77. */
  78. private float mOtherAccountAvatarRadiusDimension;
  79. /**
  80. * Reference to the drawer layout.
  81. */
  82. private DrawerLayout mDrawerLayout;
  83. /**
  84. * Reference to the drawer toggle.
  85. */
  86. protected ActionBarDrawerToggle mDrawerToggle;
  87. /**
  88. * Reference to the navigation view.
  89. */
  90. private NavigationView mNavigationView;
  91. /**
  92. * Reference to the account chooser toggle.
  93. */
  94. private ImageView mAccountChooserToggle;
  95. /**
  96. * Reference to the middle account avatar.
  97. */
  98. private ImageView mAccountMiddleAccountAvatar;
  99. /**
  100. * Reference to the end account avatar.
  101. */
  102. private ImageView mAccountEndAccountAvatar;
  103. /**
  104. * Flag to signal if the account chooser is active.
  105. */
  106. private boolean mIsAccountChooserActive;
  107. /**
  108. * Id of the checked menu item.
  109. */
  110. private int mCheckedMenuItem = Menu.NONE;
  111. /**
  112. * accounts for the (max) three displayed accounts in the drawer header.
  113. */
  114. private Account[] mAvatars = new Account[3];
  115. /**
  116. * container layout of the quota view.
  117. */
  118. private LinearLayout mQuotaView;
  119. /**
  120. * progress bar of the quota view.
  121. */
  122. private ProgressBar mQuotaProgressBar;
  123. /**
  124. * text view of the quota view.
  125. */
  126. private TextView mQuotaTextView;
  127. /**
  128. * runnable that will be executed after the drawer has been closed.
  129. */
  130. private Runnable pendingRunnable;
  131. /**
  132. * Initializes the drawer, its content and highlights the menu item with the given id.
  133. * This method needs to be called after the content view has been set.
  134. *
  135. * @param menuItemId the menu item to be checked/highlighted
  136. */
  137. protected void setupDrawer(int menuItemId) {
  138. setupDrawer();
  139. setDrawerMenuItemChecked(menuItemId);
  140. }
  141. /**
  142. * Initializes the drawer and its content.
  143. * This method needs to be called after the content view has been set.
  144. */
  145. protected void setupDrawer() {
  146. mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
  147. mNavigationView = (NavigationView) findViewById(R.id.nav_view);
  148. if (mNavigationView != null) {
  149. setupDrawerHeader();
  150. setupDrawerMenu(mNavigationView);
  151. setupQuotaElement();
  152. // show folder sync menu item only for Android 7+
  153. if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
  154. mNavigationView.getMenu().removeItem(R.id.nav_folder_sync);
  155. }
  156. }
  157. setupDrawerToggle();
  158. getSupportActionBar().setDisplayHomeAsUpEnabled(true);
  159. }
  160. /**
  161. * initializes and sets up the drawer toggle.
  162. */
  163. private void setupDrawerToggle() {
  164. mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.string.drawer_open, R.string.drawer_close) {
  165. /** Called when a drawer has settled in a completely closed state. */
  166. public void onDrawerClosed(View view) {
  167. super.onDrawerClosed(view);
  168. // standard behavior of drawer is to switch to the standard menu on closing
  169. if (mIsAccountChooserActive) {
  170. toggleAccountList();
  171. }
  172. invalidateOptionsMenu();
  173. mDrawerToggle.setDrawerIndicatorEnabled(isDrawerIndicatorAvailable());
  174. if (pendingRunnable != null) {
  175. new Handler().post(pendingRunnable);
  176. pendingRunnable = null;
  177. }
  178. }
  179. /** Called when a drawer has settled in a completely open state. */
  180. public void onDrawerOpened(View drawerView) {
  181. super.onDrawerOpened(drawerView);
  182. mDrawerToggle.setDrawerIndicatorEnabled(true);
  183. invalidateOptionsMenu();
  184. }
  185. };
  186. // Set the drawer toggle as the DrawerListener
  187. mDrawerLayout.addDrawerListener(mDrawerToggle);
  188. mDrawerToggle.setDrawerIndicatorEnabled(true);
  189. }
  190. /**
  191. * initializes and sets up the drawer header.
  192. */
  193. private void setupDrawerHeader() {
  194. mAccountChooserToggle = (ImageView) findNavigationViewChildById(R.id.drawer_account_chooser_toogle);
  195. mAccountChooserToggle.setImageResource(R.drawable.ic_down);
  196. mIsAccountChooserActive = false;
  197. mAccountMiddleAccountAvatar = (ImageView) findNavigationViewChildById(R.id.drawer_account_middle);
  198. mAccountEndAccountAvatar = (ImageView) findNavigationViewChildById(R.id.drawer_account_end);
  199. findNavigationViewChildById(R.id.drawer_active_user)
  200. .setOnClickListener(new View.OnClickListener() {
  201. @Override
  202. public void onClick(View v) {
  203. toggleAccountList();
  204. }
  205. });
  206. }
  207. /**
  208. * setup quota elements of the drawer.
  209. */
  210. private void setupQuotaElement() {
  211. mQuotaView = (LinearLayout) findViewById(R.id.drawer_quota);
  212. mQuotaProgressBar = (ProgressBar) findViewById(R.id.drawer_quota_ProgressBar);
  213. mQuotaTextView = (TextView) findViewById(R.id.drawer_quota_text);
  214. DisplayUtils.colorPreLollipopHorizontalProgressBar(mQuotaProgressBar);
  215. }
  216. /**
  217. * setup drawer content, basically setting the item selected listener.
  218. *
  219. * @param navigationView the drawers navigation view
  220. */
  221. protected void setupDrawerMenu(NavigationView navigationView) {
  222. // on pre lollipop the light theme adds a black tint to icons with white coloring
  223. // ruining the generic avatars, so tinting for icons is deactivated pre lollipop
  224. if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
  225. navigationView.setItemIconTintList(null);
  226. }
  227. // setup actions for drawer menu items
  228. navigationView.setNavigationItemSelectedListener(
  229. new NavigationView.OnNavigationItemSelectedListener() {
  230. @Override
  231. public boolean onNavigationItemSelected(final MenuItem menuItem) {
  232. mDrawerLayout.closeDrawers();
  233. // pending runnable will be executed after the drawer has been closed
  234. pendingRunnable = new Runnable() {
  235. @Override
  236. public void run() {
  237. selectNavigationItem(menuItem);
  238. }
  239. };
  240. return true;
  241. }
  242. });
  243. // handle correct state
  244. if (mIsAccountChooserActive) {
  245. navigationView.getMenu().setGroupVisible(R.id.drawer_menu_accounts, true);
  246. } else {
  247. navigationView.getMenu().setGroupVisible(R.id.drawer_menu_accounts, false);
  248. }
  249. }
  250. private void selectNavigationItem(final MenuItem menuItem) {
  251. switch (menuItem.getItemId()) {
  252. case R.id.nav_all_files:
  253. menuItem.setChecked(true);
  254. mCheckedMenuItem = menuItem.getItemId();
  255. showFiles(false);
  256. break;
  257. case R.id.nav_on_device:
  258. menuItem.setChecked(true);
  259. mCheckedMenuItem = menuItem.getItemId();
  260. showFiles(true);
  261. break;
  262. case R.id.nav_uploads:
  263. Intent uploadListIntent = new Intent(getApplicationContext(),
  264. UploadListActivity.class);
  265. uploadListIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
  266. startActivity(uploadListIntent);
  267. break;
  268. case R.id.nav_folder_sync:
  269. Intent folderSyncIntent = new Intent(getApplicationContext(),FolderSyncActivity.class);
  270. startActivity(folderSyncIntent);
  271. break;
  272. case R.id.nav_settings:
  273. Intent settingsIntent = new Intent(getApplicationContext(), Preferences.class);
  274. startActivity(settingsIntent);
  275. break;
  276. case R.id.nav_participate:
  277. Intent participateIntent = new Intent(getApplicationContext(),
  278. ParticipateActivity.class);
  279. startActivity(participateIntent);
  280. break;
  281. case R.id.drawer_menu_account_add:
  282. createAccount(false);
  283. break;
  284. case R.id.drawer_menu_account_manage:
  285. Intent manageAccountsIntent = new Intent(getApplicationContext(),
  286. ManageAccountsActivity.class);
  287. startActivityForResult(manageAccountsIntent, ACTION_MANAGE_ACCOUNTS);
  288. break;
  289. case Menu.NONE:
  290. // account clicked
  291. accountClicked(menuItem.getTitle().toString());
  292. default:
  293. Log_OC.i(TAG, "Unknown drawer menu item clicked: " + menuItem.getTitle());
  294. }
  295. }
  296. /**
  297. * show the file list to the user.
  298. *
  299. * @param onDeviceOnly flag to decide if all files or only the ones on the device should be shown
  300. */
  301. public abstract void showFiles(boolean onDeviceOnly);
  302. /**
  303. * sets the new/current account and restarts. In case the given account equals the actual/current account the
  304. * call will be ignored.
  305. *
  306. * @param accountName The account name to be set
  307. */
  308. private void accountClicked(String accountName) {
  309. if (!AccountUtils.getCurrentOwnCloudAccount(getApplicationContext()).name.equals(accountName)) {
  310. AccountUtils.setCurrentOwnCloudAccount(getApplicationContext(), accountName);
  311. restart();
  312. }
  313. }
  314. /**
  315. * click method for mini avatars in drawer header.
  316. *
  317. * @param view the clicked ImageView
  318. */
  319. public void onAccountDrawerClick(View view) {
  320. accountClicked(view.getContentDescription().toString());
  321. }
  322. /**
  323. * checks if the drawer exists and is opened.
  324. *
  325. * @return <code>true</code> if the drawer is open, else <code>false</code>
  326. */
  327. public boolean isDrawerOpen() {
  328. return mDrawerLayout != null && mDrawerLayout.isDrawerOpen(GravityCompat.START);
  329. }
  330. /**
  331. * closes the drawer.
  332. */
  333. public void closeDrawer() {
  334. if (mDrawerLayout != null) {
  335. mDrawerLayout.closeDrawer(GravityCompat.START);
  336. }
  337. }
  338. /**
  339. * opens the drawer.
  340. */
  341. public void openDrawer() {
  342. if (mDrawerLayout != null) {
  343. mDrawerLayout.openDrawer(GravityCompat.START);
  344. }
  345. }
  346. /**
  347. * Enable or disable interaction with all drawers.
  348. *
  349. * @param lockMode The new lock mode for the given drawer. One of {@link DrawerLayout#LOCK_MODE_UNLOCKED},
  350. * {@link DrawerLayout#LOCK_MODE_LOCKED_CLOSED} or {@link DrawerLayout#LOCK_MODE_LOCKED_OPEN}.
  351. */
  352. public void setDrawerLockMode(int lockMode) {
  353. if (mDrawerLayout != null) {
  354. mDrawerLayout.setDrawerLockMode(lockMode);
  355. }
  356. }
  357. /**
  358. * Enable or disable the drawer indicator.
  359. *
  360. * @param enable <code>true</code> to enable, <code>false</code> to disable
  361. */
  362. public void setDrawerIndicatorEnabled(boolean enable) {
  363. if (mDrawerToggle != null) {
  364. mDrawerToggle.setDrawerIndicatorEnabled(enable);
  365. }
  366. }
  367. /**
  368. * updates the account list in the drawer.
  369. */
  370. public void updateAccountList() {
  371. Account[] accounts = AccountManager.get(this).getAccountsByType(MainApp.getAccountType());
  372. if (mNavigationView != null && mDrawerLayout != null) {
  373. if (accounts.length > 0) {
  374. repopulateAccountList(accounts);
  375. setAccountInDrawer(AccountUtils.getCurrentOwnCloudAccount(this));
  376. populateDrawerOwnCloudAccounts();
  377. // activate second/end account avatar
  378. if (mAvatars[1] != null) {
  379. DisplayUtils.setAvatar(mAvatars[1], this,
  380. mOtherAccountAvatarRadiusDimension, getResources(), getStorageManager(),
  381. findNavigationViewChildById(R.id.drawer_account_end));
  382. mAccountEndAccountAvatar.setVisibility(View.VISIBLE);
  383. } else {
  384. mAccountEndAccountAvatar.setVisibility(View.GONE);
  385. }
  386. // activate third/middle account avatar
  387. if (mAvatars[2] != null) {
  388. DisplayUtils.setAvatar(mAvatars[2], this,
  389. mOtherAccountAvatarRadiusDimension, getResources(), getStorageManager(),
  390. findNavigationViewChildById(R.id.drawer_account_middle));
  391. mAccountMiddleAccountAvatar.setVisibility(View.VISIBLE);
  392. } else {
  393. mAccountMiddleAccountAvatar.setVisibility(View.GONE);
  394. }
  395. } else {
  396. mAccountEndAccountAvatar.setVisibility(View.GONE);
  397. mAccountMiddleAccountAvatar.setVisibility(View.GONE);
  398. }
  399. }
  400. }
  401. /**
  402. * re-populates the account list.
  403. *
  404. * @param accounts list of accounts
  405. */
  406. private void repopulateAccountList(Account[] accounts) {
  407. // remove all accounts from list
  408. mNavigationView.getMenu().removeGroup(R.id.drawer_menu_accounts);
  409. // add all accounts to list
  410. for (int i = 0; i < accounts.length; i++) {
  411. try {
  412. // show all accounts except the currently active one
  413. if (!getAccount().name.equals(accounts[i].name)) {
  414. MenuItem accountMenuItem = mNavigationView.getMenu().add(
  415. R.id.drawer_menu_accounts,
  416. Menu.NONE,
  417. MENU_ORDER_ACCOUNT,
  418. accounts[i].name)
  419. .setIcon(TextDrawable.createAvatar(
  420. accounts[i].name,
  421. mMenuAccountAvatarRadiusDimension)
  422. );
  423. DisplayUtils.setAvatar(accounts[i], this, mMenuAccountAvatarRadiusDimension, getResources(), getStorageManager(), accountMenuItem);
  424. }
  425. } catch (Exception e) {
  426. Log_OC.e(TAG, "Error calculating RGB value for account menu item.", e);
  427. mNavigationView.getMenu().add(
  428. R.id.drawer_menu_accounts,
  429. Menu.NONE,
  430. MENU_ORDER_ACCOUNT,
  431. accounts[i].name)
  432. .setIcon(R.drawable.ic_user);
  433. }
  434. }
  435. // re-add add-account and manage-accounts
  436. mNavigationView.getMenu().add(R.id.drawer_menu_accounts, R.id.drawer_menu_account_add,
  437. MENU_ORDER_ACCOUNT_FUNCTION,
  438. getResources().getString(R.string.prefs_add_account)).setIcon(R.drawable.ic_account_plus);
  439. mNavigationView.getMenu().add(R.id.drawer_menu_accounts, R.id.drawer_menu_account_manage,
  440. MENU_ORDER_ACCOUNT_FUNCTION,
  441. getResources().getString(R.string.drawer_manage_accounts)).setIcon(R.drawable.ic_settings);
  442. // adding sets menu group back to visible, so safety check and setting invisible
  443. showMenu();
  444. }
  445. /**
  446. * Updates title bar and home buttons (state and icon).
  447. * <p/>
  448. * Assumes that navigation drawer is NOT visible.
  449. */
  450. protected void updateActionBarTitleAndHomeButton(OCFile chosenFile) {
  451. super.updateActionBarTitleAndHomeButton(chosenFile);
  452. /// set home button properties
  453. if (mDrawerToggle != null && chosenFile != null) {
  454. mDrawerToggle.setDrawerIndicatorEnabled(isRoot(chosenFile));
  455. } else {
  456. mDrawerToggle.setDrawerIndicatorEnabled(false);
  457. }
  458. }
  459. /**
  460. * sets the given account name in the drawer in case the drawer is available. The account name is shortened
  461. * beginning from the @-sign in the username.
  462. *
  463. * @param account the account to be set in the drawer
  464. */
  465. protected void setAccountInDrawer(Account account) {
  466. if (mDrawerLayout != null && account != null) {
  467. TextView username = (TextView) findNavigationViewChildById(R.id.drawer_username);
  468. TextView usernameFull = (TextView) findNavigationViewChildById(R.id.drawer_username_full);
  469. usernameFull.setText(account.name);
  470. try {
  471. OwnCloudAccount oca = new OwnCloudAccount(account, this);
  472. username.setText(oca.getDisplayName());
  473. } catch (com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException e) {
  474. Log_OC.w(TAG, "Couldn't read display name of account fallback to account name");
  475. username.setText(AccountUtils.getAccountUsername(account.name));
  476. }
  477. DisplayUtils.setAvatar(account, this,
  478. mCurrentAccountAvatarRadiusDimension, getResources(), getStorageManager(),
  479. findNavigationViewChildById(R.id.drawer_current_account));
  480. // check and show quota info if available
  481. getAndDisplayUserQuota();
  482. }
  483. }
  484. /**
  485. * Toggle between standard menu and account list including saving the state.
  486. */
  487. private void toggleAccountList() {
  488. mIsAccountChooserActive = !mIsAccountChooserActive;
  489. showMenu();
  490. }
  491. /**
  492. * depending on the #mIsAccountChooserActive flag shows the account chooser or the standard menu.
  493. */
  494. private void showMenu() {
  495. if (mNavigationView != null) {
  496. if (mIsAccountChooserActive) {
  497. mAccountChooserToggle.setImageResource(R.drawable.ic_up);
  498. mNavigationView.getMenu().setGroupVisible(R.id.drawer_menu_accounts, true);
  499. mNavigationView.getMenu().setGroupVisible(R.id.drawer_menu_standard, false);
  500. mNavigationView.getMenu().setGroupVisible(R.id.drawer_menu_bottom, false);
  501. } else {
  502. mAccountChooserToggle.setImageResource(R.drawable.ic_down);
  503. mNavigationView.getMenu().setGroupVisible(R.id.drawer_menu_accounts, false);
  504. mNavigationView.getMenu().setGroupVisible(R.id.drawer_menu_standard, true);
  505. mNavigationView.getMenu().setGroupVisible(R.id.drawer_menu_bottom, true);
  506. }
  507. }
  508. }
  509. /**
  510. * shows or hides the quota UI elements.
  511. *
  512. * @param showQuota show/hide quota information
  513. */
  514. private void showQuota(boolean showQuota) {
  515. if (showQuota) {
  516. mQuotaView.setVisibility(View.VISIBLE);
  517. } else {
  518. mQuotaView.setVisibility(View.GONE);
  519. }
  520. }
  521. /**
  522. * configured the quota to be displayed.
  523. *
  524. * @param usedSpace the used space
  525. * @param totalSpace the total space
  526. * @param relative the percentage of space already used
  527. */
  528. private void setQuotaInformation(long usedSpace, long totalSpace, int relative) {
  529. mQuotaProgressBar.setProgress(relative);
  530. DisplayUtils.colorHorizontalProgressBar(mQuotaProgressBar, DisplayUtils.getRelativeInfoColor(this, relative));
  531. mQuotaTextView.setText(String.format(
  532. getString(R.string.drawer_quota),
  533. DisplayUtils.bytesToHumanReadable(usedSpace),
  534. DisplayUtils.bytesToHumanReadable(totalSpace)));
  535. showQuota(true);
  536. }
  537. /**
  538. * checks/highlights the provided menu item if the drawer has been initialized and the menu item exists.
  539. *
  540. * @param menuItemId the menu item to be highlighted
  541. */
  542. protected void setDrawerMenuItemChecked(int menuItemId) {
  543. if (mNavigationView != null && mNavigationView.getMenu() != null && mNavigationView.getMenu().findItem
  544. (menuItemId) != null) {
  545. mNavigationView.getMenu().findItem(menuItemId).setChecked(true);
  546. mCheckedMenuItem = menuItemId;
  547. } else {
  548. Log_OC.w(TAG, "setDrawerMenuItemChecked has been called with invalid menu-item-ID");
  549. }
  550. }
  551. /**
  552. * Retrieves and shows the user quota if available
  553. */
  554. private void getAndDisplayUserQuota() {
  555. // set user space information
  556. Thread t = new Thread(new Runnable() {
  557. public void run() {
  558. RemoteOperation getQuotaInfoOperation = new GetRemoteUserInfoOperation();
  559. RemoteOperationResult result = getQuotaInfoOperation.execute(
  560. AccountUtils.getCurrentOwnCloudAccount(DrawerActivity.this), DrawerActivity.this);
  561. if (result.isSuccess() && result.getData() != null) {
  562. final UserInfo userInfo = (UserInfo) result.getData().get(0);
  563. final Quota quota = userInfo.getQuota();
  564. final long used = quota.getUsed();
  565. final long total = quota.getTotal();
  566. final int relative = (int) Math.ceil(quota.getRelative());
  567. final long quotaValue = quota.getQuota();
  568. runOnUiThread(new Runnable() {
  569. @Override
  570. public void run() {
  571. if (quotaValue > 0
  572. || quotaValue == GetRemoteUserInfoOperation.QUOTA_LIMIT_INFO_NOT_AVAILABLE) {
  573. /**
  574. * show quota in case
  575. * it is available and calculated (> 0) or
  576. * in case of legacy servers (==QUOTA_LIMIT_INFO_NOT_AVAILABLE)
  577. */
  578. setQuotaInformation(used, total, relative);
  579. } else {
  580. /**
  581. * quotaValue < 0 means special cases like
  582. * {@link RemoteGetUserQuotaOperation.SPACE_NOT_COMPUTED},
  583. * {@link RemoteGetUserQuotaOperation.SPACE_UNKNOWN} or
  584. * {@link RemoteGetUserQuotaOperation.SPACE_UNLIMITED}
  585. * thus don't display any quota information.
  586. */
  587. showQuota(false);
  588. }
  589. }
  590. });
  591. }
  592. }
  593. });
  594. t.start();
  595. }
  596. @Override
  597. protected void onCreate(Bundle savedInstanceState) {
  598. super.onCreate(savedInstanceState);
  599. if (savedInstanceState != null) {
  600. mIsAccountChooserActive = savedInstanceState.getBoolean(KEY_IS_ACCOUNT_CHOOSER_ACTIVE, false);
  601. mCheckedMenuItem = savedInstanceState.getInt(KEY_CHECKED_MENU_ITEM, Menu.NONE);
  602. }
  603. mCurrentAccountAvatarRadiusDimension = getResources()
  604. .getDimension(R.dimen.nav_drawer_header_avatar_radius);
  605. mOtherAccountAvatarRadiusDimension = getResources()
  606. .getDimension(R.dimen.nav_drawer_header_avatar_other_accounts_radius);
  607. mMenuAccountAvatarRadiusDimension = getResources()
  608. .getDimension(R.dimen.nav_drawer_menu_avatar_radius);
  609. }
  610. @Override
  611. protected void onSaveInstanceState(Bundle outState) {
  612. super.onSaveInstanceState(outState);
  613. outState.putBoolean(KEY_IS_ACCOUNT_CHOOSER_ACTIVE, mIsAccountChooserActive);
  614. outState.putInt(KEY_CHECKED_MENU_ITEM, mCheckedMenuItem);
  615. }
  616. @Override
  617. public void onRestoreInstanceState(Bundle savedInstanceState) {
  618. super.onRestoreInstanceState(savedInstanceState);
  619. mIsAccountChooserActive = savedInstanceState.getBoolean(KEY_IS_ACCOUNT_CHOOSER_ACTIVE, false);
  620. mCheckedMenuItem = savedInstanceState.getInt(KEY_CHECKED_MENU_ITEM, Menu.NONE);
  621. // (re-)setup drawer state
  622. showMenu();
  623. // check/highlight the menu item if present
  624. if (mCheckedMenuItem > Menu.NONE || mCheckedMenuItem < Menu.NONE) {
  625. setDrawerMenuItemChecked(mCheckedMenuItem);
  626. }
  627. }
  628. @Override
  629. protected void onPostCreate(Bundle savedInstanceState) {
  630. super.onPostCreate(savedInstanceState);
  631. // Sync the toggle state after onRestoreInstanceState has occurred.
  632. if (mDrawerToggle != null) {
  633. mDrawerToggle.syncState();
  634. if (isDrawerOpen()) {
  635. mDrawerToggle.setDrawerIndicatorEnabled(true);
  636. }
  637. }
  638. updateAccountList();
  639. }
  640. @Override
  641. public void onConfigurationChanged(Configuration newConfig) {
  642. super.onConfigurationChanged(newConfig);
  643. if (mDrawerToggle != null) {
  644. mDrawerToggle.onConfigurationChanged(newConfig);
  645. }
  646. }
  647. @Override
  648. public void onBackPressed() {
  649. if (isDrawerOpen()) {
  650. closeDrawer();
  651. return;
  652. }
  653. super.onBackPressed();
  654. }
  655. @Override
  656. protected void onResume() {
  657. super.onResume();
  658. setDrawerMenuItemChecked(mCheckedMenuItem);
  659. }
  660. @Override
  661. protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  662. super.onActivityResult(requestCode, resultCode, data);
  663. // update Account list and active account if Manage Account activity replies with
  664. // - ACCOUNT_LIST_CHANGED = true
  665. // - RESULT_OK
  666. if (requestCode == ACTION_MANAGE_ACCOUNTS
  667. && resultCode == RESULT_OK
  668. && data.getBooleanExtra(ManageAccountsActivity.KEY_ACCOUNT_LIST_CHANGED, false)) {
  669. // current account has changed
  670. if (data.getBooleanExtra(ManageAccountsActivity.KEY_CURRENT_ACCOUNT_CHANGED, false)) {
  671. setAccount(AccountUtils.getCurrentOwnCloudAccount(this));
  672. restart();
  673. } else {
  674. updateAccountList();
  675. }
  676. }
  677. }
  678. /**
  679. * Finds a view that was identified by the id attribute from the drawer header.
  680. *
  681. * @param id the view's id
  682. * @return The view if found or <code>null</code> otherwise.
  683. */
  684. private View findNavigationViewChildById(int id) {
  685. return ((NavigationView) findViewById(R.id.nav_view)).getHeaderView(0).findViewById(id);
  686. }
  687. /**
  688. * restart helper method which is called after a changing the current account.
  689. */
  690. protected abstract void restart();
  691. @Override
  692. protected void onAccountCreationSuccessful(AccountManagerFuture<Bundle> future) {
  693. super.onAccountCreationSuccessful(future);
  694. updateAccountList();
  695. restart();
  696. }
  697. /**
  698. * populates the avatar drawer array with the first three ownCloud {@link Account}s while the first element is
  699. * always the current account.
  700. */
  701. private void populateDrawerOwnCloudAccounts() {
  702. mAvatars = new Account[3];
  703. Account[] accountsAll = AccountManager.get(this).getAccountsByType
  704. (MainApp.getAccountType());
  705. Account currentAccount = AccountUtils.getCurrentOwnCloudAccount(this);
  706. mAvatars[0] = currentAccount;
  707. int j = 0;
  708. for (int i = 1; i <= 2 && i < accountsAll.length && j < accountsAll.length; j++) {
  709. if (!currentAccount.equals(accountsAll[j])) {
  710. mAvatars[i] = accountsAll[j];
  711. i++;
  712. }
  713. }
  714. }
  715. @Override
  716. public void avatarGenerated(Drawable avatarDrawable, Object callContext) {
  717. if (callContext instanceof MenuItem) {
  718. MenuItem mi = (MenuItem)callContext;
  719. mi.setIcon(avatarDrawable);
  720. } else if (callContext instanceof ImageView) {
  721. ImageView iv = (ImageView)callContext;
  722. iv.setImageDrawable(avatarDrawable);
  723. }
  724. }
  725. @Override
  726. public boolean shouldCallGeneratedCallback(String tag, Object callContext) {
  727. if (callContext instanceof MenuItem) {
  728. MenuItem mi = (MenuItem)callContext;
  729. return String.valueOf(mi.getTitle()).equals(tag);
  730. } else if (callContext instanceof ImageView) {
  731. ImageView iv = (ImageView)callContext;
  732. return String.valueOf(iv.getTag()).equals(tag);
  733. }
  734. return false;
  735. }
  736. /**
  737. * Adds other listeners to react on changes of the drawer layout.
  738. *
  739. * @param listener Object interested in changes of the drawer layout.
  740. */
  741. public void addDrawerListener(DrawerLayout.DrawerListener listener) {
  742. if (mDrawerLayout != null) {
  743. mDrawerLayout.addDrawerListener(listener);
  744. } else {
  745. Log_OC.e(TAG, "Drawer layout not ready to add drawer listener");
  746. }
  747. }
  748. public boolean isDrawerIndicatorAvailable() {
  749. return true;
  750. }
  751. }