FileDetailSharingFragment.java 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612
  1. /*
  2. * Nextcloud Android client application
  3. *
  4. * @author Andy Scherzinger
  5. * @author Chris Narkiewicz <hello@ezaquarii.com>
  6. *
  7. * Copyright (C) 2018 Andy Scherzinger
  8. * Copyright (C) 2020 Chris Narkiewicz <hello@ezaquarii.com>
  9. *
  10. * This program is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
  12. * License as published by the Free Software Foundation; either
  13. * version 3 of the License, or any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
  19. *
  20. * You should have received a copy of the GNU Affero General Public
  21. * License along with this program. If not, see <http://www.gnu.org/licenses/>.
  22. */
  23. package com.owncloud.android.ui.fragment;
  24. import android.accounts.Account;
  25. import android.accounts.AccountManager;
  26. import android.app.SearchManager;
  27. import android.content.Context;
  28. import android.content.res.Resources;
  29. import android.graphics.PorterDuff;
  30. import android.graphics.drawable.Drawable;
  31. import android.os.Bundle;
  32. import android.text.InputType;
  33. import android.text.TextUtils;
  34. import android.view.LayoutInflater;
  35. import android.view.Menu;
  36. import android.view.MenuItem;
  37. import android.view.View;
  38. import android.view.ViewGroup;
  39. import android.widget.ImageView;
  40. import android.widget.LinearLayout;
  41. import android.widget.TextView;
  42. import com.google.android.material.snackbar.Snackbar;
  43. import com.nextcloud.client.account.User;
  44. import com.nextcloud.client.account.UserAccountManager;
  45. import com.nextcloud.client.di.Injectable;
  46. import com.owncloud.android.R;
  47. import com.owncloud.android.datamodel.FileDataStorageManager;
  48. import com.owncloud.android.datamodel.OCFile;
  49. import com.owncloud.android.lib.common.OwnCloudAccount;
  50. import com.owncloud.android.lib.common.operations.RemoteOperationResult;
  51. import com.owncloud.android.lib.resources.shares.OCShare;
  52. import com.owncloud.android.lib.resources.shares.SharePermissionsBuilder;
  53. import com.owncloud.android.lib.resources.shares.ShareType;
  54. import com.owncloud.android.lib.resources.status.OCCapability;
  55. import com.owncloud.android.ui.activity.FileActivity;
  56. import com.owncloud.android.ui.activity.FileDisplayActivity;
  57. import com.owncloud.android.ui.adapter.PublicShareInterface;
  58. import com.owncloud.android.ui.adapter.PublicShareListAdapter;
  59. import com.owncloud.android.ui.adapter.ShareeListAdapter;
  60. import com.owncloud.android.ui.decoration.SimpleListItemDividerDecoration;
  61. import com.owncloud.android.ui.dialog.ExpirationDatePickerDialogFragment;
  62. import com.owncloud.android.ui.dialog.NoteDialogFragment;
  63. import com.owncloud.android.ui.dialog.SharePasswordDialogFragment;
  64. import com.owncloud.android.ui.fragment.util.FileDetailSharingFragmentHelper;
  65. import com.owncloud.android.ui.fragment.util.SharingMenuHelper;
  66. import com.owncloud.android.ui.helpers.FileOperationsHelper;
  67. import com.owncloud.android.utils.ClipboardUtil;
  68. import com.owncloud.android.utils.DisplayUtils;
  69. import com.owncloud.android.utils.ThemeUtils;
  70. import java.util.List;
  71. import javax.inject.Inject;
  72. import androidx.annotation.NonNull;
  73. import androidx.annotation.Nullable;
  74. import androidx.appcompat.widget.PopupMenu;
  75. import androidx.appcompat.widget.SearchView;
  76. import androidx.fragment.app.Fragment;
  77. import androidx.recyclerview.widget.LinearLayoutManager;
  78. import androidx.recyclerview.widget.RecyclerView;
  79. import butterknife.BindView;
  80. import butterknife.ButterKnife;
  81. import butterknife.OnClick;
  82. import butterknife.Unbinder;
  83. public class FileDetailSharingFragment extends Fragment implements ShareeListAdapter.ShareeListAdapterListener,
  84. DisplayUtils.AvatarGenerationListener,
  85. PublicShareInterface,
  86. Injectable {
  87. private static final String ARG_FILE = "FILE";
  88. private static final String ARG_USER = "USER";
  89. public static final int PERMISSION_EDITING_ALLOWED = 17;
  90. // to show share with users/groups info
  91. private List<OCShare> shares;
  92. private OCFile file;
  93. private User user;
  94. private OCCapability capabilities;
  95. private FileOperationsHelper fileOperationsHelper;
  96. private FileActivity fileActivity;
  97. private FileDataStorageManager fileDataStorageManager;
  98. private Unbinder unbinder;
  99. @BindView(R.id.searchView)
  100. SearchView searchView;
  101. @BindView(R.id.shareUsersList)
  102. RecyclerView usersList;
  103. @BindView(R.id.publicShareList)
  104. RecyclerView publicShareList;
  105. @BindView(R.id.new_public_share)
  106. View addPublicShare;
  107. @BindView(R.id.shared_with_you_container)
  108. LinearLayout sharedWithYouContainer;
  109. @BindView(R.id.shared_with_you_avatar)
  110. ImageView sharedWithYouAvatar;
  111. @BindView(R.id.shared_with_you_username)
  112. TextView sharedWithYouUsername;
  113. @BindView(R.id.shared_with_you_note_container)
  114. View sharedWithYouNoteContainer;
  115. @BindView(R.id.shared_with_you_note)
  116. TextView sharedWithYouNote;
  117. @BindView(R.id.copy_internal_link_icon)
  118. ImageView internalLinkIcon;
  119. @BindView(R.id.shareInternalLinkText)
  120. TextView internalLinkText;
  121. @Inject UserAccountManager accountManager;
  122. public static FileDetailSharingFragment newInstance(OCFile file, User user) {
  123. FileDetailSharingFragment fragment = new FileDetailSharingFragment();
  124. Bundle args = new Bundle();
  125. args.putParcelable(ARG_FILE, file);
  126. args.putParcelable(ARG_USER, user);
  127. fragment.setArguments(args);
  128. return fragment;
  129. }
  130. @Override
  131. public void onCreate(@Nullable Bundle savedInstanceState) {
  132. super.onCreate(savedInstanceState);
  133. if (savedInstanceState != null) {
  134. file = savedInstanceState.getParcelable(ARG_FILE);
  135. user = savedInstanceState.getParcelable(ARG_USER);
  136. } else {
  137. Bundle arguments = getArguments();
  138. if (arguments != null) {
  139. file = getArguments().getParcelable(ARG_FILE);
  140. user = getArguments().getParcelable(ARG_USER);
  141. }
  142. }
  143. if (file == null) {
  144. throw new IllegalArgumentException("File may not be null");
  145. }
  146. if (user == null) {
  147. throw new IllegalArgumentException("Account may not be null");
  148. }
  149. fileActivity = (FileActivity) getActivity();
  150. if (fileActivity == null) {
  151. throw new IllegalArgumentException("FileActivity may not be null");
  152. }
  153. }
  154. @Override
  155. public void onActivityCreated(Bundle savedInstanceState) {
  156. super.onActivityCreated(savedInstanceState);
  157. refreshCapabilitiesFromDB();
  158. refreshPublicShareFromDB();
  159. }
  160. @Override
  161. public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
  162. View view = inflater.inflate(R.layout.file_details_sharing_fragment, container, false);
  163. unbinder = ButterKnife.bind(this, view);
  164. fileOperationsHelper = fileActivity.getFileOperationsHelper();
  165. fileDataStorageManager = fileActivity.getStorageManager();
  166. setupView();
  167. // todo extract
  168. internalLinkIcon.getBackground().setColorFilter(getResources().getColor(R.color.grey_db),
  169. PorterDuff.Mode.SRC_IN);
  170. internalLinkIcon.getDrawable().mutate().setColorFilter(getResources().getColor(R.color.black),
  171. PorterDuff.Mode.SRC_IN);
  172. if (file.isFolder()) {
  173. internalLinkText.setText(getString(R.string.share_internal_link_to_folder_text));
  174. } else {
  175. internalLinkText.setText(getString(R.string.share_internal_link_to_file_text));
  176. }
  177. return view;
  178. }
  179. @Override
  180. public void onDestroy() {
  181. super.onDestroy();
  182. unbinder.unbind();
  183. }
  184. @Override
  185. public void onAttach(@NonNull Context context) {
  186. super.onAttach(context);
  187. if (!(getActivity() instanceof FileActivity)) {
  188. throw new IllegalArgumentException("Calling activity must be of type FileActivity");
  189. }
  190. }
  191. private void setupView() {
  192. setShareWithYou();
  193. FileDetailSharingFragmentHelper.setupSearchView(
  194. (SearchManager) fileActivity.getSystemService(Context.SEARCH_SERVICE), searchView,
  195. fileActivity.getComponentName());
  196. ThemeUtils.themeSearchView(searchView, requireContext());
  197. if (file.canReshare()) {
  198. setShareWithUserInfo();
  199. } else {
  200. searchView.setQueryHint(getResources().getString(R.string.reshare_not_allowed));
  201. searchView.setInputType(InputType.TYPE_NULL);
  202. disableSearchView(searchView);
  203. }
  204. }
  205. private void disableSearchView(View view) {
  206. view.setEnabled(false);
  207. if (view instanceof ViewGroup) {
  208. ViewGroup viewGroup = (ViewGroup) view;
  209. for (int i = 0; i < viewGroup.getChildCount(); i++) {
  210. disableSearchView(viewGroup.getChildAt(i));
  211. }
  212. }
  213. }
  214. private void setShareWithYou() {
  215. if (accountManager.userOwnsFile(file, user)) {
  216. sharedWithYouContainer.setVisibility(View.GONE);
  217. } else {
  218. sharedWithYouUsername.setText(
  219. String.format(getString(R.string.shared_with_you_by), file.getOwnerDisplayName()));
  220. DisplayUtils.setAvatar(user, file.getOwnerId(), this, getResources().getDimension(
  221. R.dimen.file_list_item_avatar_icon_radius), getResources(), sharedWithYouAvatar,
  222. getContext());
  223. sharedWithYouAvatar.setVisibility(View.VISIBLE);
  224. String note = file.getNote();
  225. if (!TextUtils.isEmpty(note)) {
  226. sharedWithYouNote.setText(file.getNote());
  227. sharedWithYouNoteContainer.setVisibility(View.VISIBLE);
  228. } else {
  229. sharedWithYouNoteContainer.setVisibility(View.GONE);
  230. }
  231. }
  232. }
  233. private void setShareWithUserInfo() {
  234. // TODO Refactoring: create a new {@link ShareUserListAdapter} instance with every call should not be needed
  235. shares = fileDataStorageManager.getSharesWithForAFile(file.getRemotePath(), account.name);
  236. if (shares.size() > 0) {
  237. AccountManager accountManager = AccountManager.get(getContext());
  238. String userId = accountManager.getUserData(user.toPlatformAccount(),
  239. com.owncloud.android.lib.common.accounts.AccountUtils.Constants.KEY_USER_ID);
  240. usersList.setVisibility(View.VISIBLE);
  241. usersList.setAdapter(new ShareeListAdapter(fileActivity.getSupportFragmentManager(),
  242. fileActivity,
  243. shares,
  244. user.toPlatformAccount(),
  245. file,
  246. this,
  247. userId));
  248. usersList.setLayoutManager(new LinearLayoutManager(getContext()));
  249. usersList.addItemDecoration(new SimpleListItemDividerDecoration(getContext()));
  250. } else {
  251. usersList.setVisibility(View.GONE);
  252. }
  253. }
  254. @OnClick(R.id.copy_internal_container)
  255. public void copyInternalLink() {
  256. OwnCloudAccount account = accountManager.getCurrentOwnCloudAccount();
  257. if (account == null) {
  258. DisplayUtils.showSnackMessage(getView(), getString(R.string.could_not_retrieve_url));
  259. return;
  260. }
  261. FileDisplayActivity.showShareLinkDialog(fileActivity, file, createInternalLink(account, file));
  262. }
  263. private String createInternalLink(OwnCloudAccount account, OCFile file) {
  264. return account.getBaseUri() + "/index.php/f/" + file.getLocalId();
  265. }
  266. private void createShareLink() {
  267. if (capabilities != null && (capabilities.getFilesSharingPublicPasswordEnforced().isTrue() ||
  268. capabilities.getFilesSharingPublicAskForOptionalPassword().isTrue())) {
  269. // password enforced by server, request to the user before trying to create
  270. requestPasswordForShareViaLink(true,
  271. capabilities.getFilesSharingPublicAskForOptionalPassword().isTrue());
  272. } else {
  273. // create without password if not enforced by server or we don't know if enforced;
  274. fileOperationsHelper.shareFileViaLink(file, null);
  275. }
  276. }
  277. private void showSendLinkTo() {
  278. if (file.isSharedViaLink()) {
  279. if (TextUtils.isEmpty(file.getPublicLink())) {
  280. fileOperationsHelper.getFileWithLink(file);
  281. } else {
  282. FileDisplayActivity.showShareLinkDialog(fileActivity, file, file.getPublicLink());
  283. }
  284. }
  285. }
  286. public void copyLink(OCShare share) {
  287. if (file.isSharedViaLink()) {
  288. if (TextUtils.isEmpty(file.getPublicLink())) {
  289. fileOperationsHelper.getFileWithLink(file);
  290. } else {
  291. ClipboardUtil.copyToClipboard(getActivity(), file.getPublicLink());
  292. }
  293. }
  294. }
  295. public void showLinkOverflowMenu(OCShare publicShare, ImageView overflowMenuShareLink) {
  296. if (ThemeUtils.themingEnabled(requireContext())) {
  297. // use grey as fallback for elements where custom theming is not available
  298. requireContext().getTheme().applyStyle(R.style.FallbackThemingTheme, true);
  299. }
  300. PopupMenu popup = new PopupMenu(requireContext(), overflowMenuShareLink);
  301. popup.inflate(R.menu.fragment_file_detail_sharing_link);
  302. prepareOptionsMenu(popup.getMenu(), publicShare);
  303. popup.setOnMenuItemClickListener(menuItem -> optionsItemSelected(menuItem, publicShare));
  304. popup.show();
  305. }
  306. private void prepareOptionsMenu(Menu menu, OCShare publicShare) {
  307. Resources res = requireContext().getResources();
  308. SharingMenuHelper.setupHideFileListingMenuItem(menu.findItem(R.id.action_hide_file_listing),
  309. file.isFolder(),
  310. menu.findItem(R.id.action_allow_editing).isChecked(),
  311. publicShare.getPermissions());
  312. SharingMenuHelper.setupHideFileDownload(menu.findItem(R.id.action_hide_file_download),
  313. publicShare.isHideFileDownload(),
  314. capabilities);
  315. SharingMenuHelper.setupPasswordMenuItem(menu.findItem(R.id.action_password),
  316. publicShare.isPasswordProtected());
  317. SharingMenuHelper.setupExpirationDateMenuItem(menu.findItem(R.id.action_share_expiration_date),
  318. publicShare.getExpirationDate(),
  319. res);
  320. menu.findItem(R.id.action_share_send_note).setVisible(capabilities.getVersion().isNoteOnShareSupported());
  321. if (publicShare.getPermissions() > PERMISSION_EDITING_ALLOWED) {
  322. menu.findItem(R.id.action_allow_editing).setChecked(true);
  323. } else {
  324. menu.findItem(R.id.action_allow_editing).setChecked(false);
  325. }
  326. }
  327. public boolean optionsItemSelected(MenuItem item, OCShare publicShare) {
  328. switch (item.getItemId()) {
  329. case R.id.action_allow_editing:
  330. if (file.isSharedViaLink()) {
  331. item.setChecked(!item.isChecked());
  332. fileOperationsHelper.setUploadPermissionsToShare(file,
  333. item.isChecked());
  334. }
  335. return true;
  336. case R.id.action_hide_file_listing: {
  337. item.setChecked(!item.isChecked());
  338. if (capabilities.getFilesFileDrop().isTrue()) {
  339. setHideFileListingPermissionsToShare(publicShare, item.isChecked());
  340. } else {
  341. // not supported in ownCloud
  342. showNotSupportedByOcMessage();
  343. }
  344. return true;
  345. }
  346. case R.id.action_hide_file_download:
  347. item.setChecked(!item.isChecked());
  348. setHideFileDownloadPermissionToShare(file, item.isChecked());
  349. return true;
  350. case R.id.action_password: {
  351. requestPasswordForShareViaLink(false,
  352. capabilities.getFilesSharingPublicAskForOptionalPassword().isTrue());
  353. return true;
  354. }
  355. case R.id.action_share_expiration_date: {
  356. ExpirationDatePickerDialogFragment dialog = ExpirationDatePickerDialogFragment
  357. .newInstance(file, publicShare.getExpirationDate());
  358. dialog.show(fileActivity.getSupportFragmentManager(),
  359. ExpirationDatePickerDialogFragment.DATE_PICKER_DIALOG);
  360. return true;
  361. }
  362. case R.id.action_share_send_link: {
  363. if (file.isSharedViaLink() && !TextUtils.isEmpty(file.getPublicLink())) {
  364. FileDisplayActivity.showShareLinkDialog(fileActivity, file, file.getPublicLink());
  365. } else {
  366. showSendLinkTo();
  367. }
  368. return true;
  369. }
  370. case R.id.action_share_send_note:
  371. NoteDialogFragment dialog = NoteDialogFragment.newInstance(publicShare);
  372. dialog.show(fileActivity.getSupportFragmentManager(), NoteDialogFragment.NOTE_FRAGMENT);
  373. return true;
  374. case R.id.action_add_another_public_share_link:
  375. createShareLink();
  376. return true;
  377. case R.id.action_unshare:
  378. fileOperationsHelper.unshareShare(file, publicShare);
  379. default:
  380. return super.onOptionsItemSelected(item);
  381. }
  382. }
  383. @Override
  384. public void setHideFileListingPermissionsToShare(OCShare share, boolean hideFileListing) {
  385. fileOperationsHelper.setHideFileListingPermissionsToShare(share, hideFileListing);
  386. }
  387. @Override
  388. public void setHideFileDownloadPermissionToShare(OCFile file, boolean hideFileDownload) {
  389. fileOperationsHelper.setHideFileDownloadPermissionsToShare(file, hideFileDownload);
  390. }
  391. @Override
  392. public void showNotSupportedByOcMessage() {
  393. if (getView() != null) {
  394. Snackbar.make(getView(), R.string.files_drop_not_supported, Snackbar.LENGTH_LONG)
  395. .setAction(R.string.learn_more, v ->
  396. DisplayUtils.startLinkIntent(requireActivity(), R.string.url_server_install))
  397. .show();
  398. }
  399. }
  400. /**
  401. * Updates the UI after the result of an update operation on the edited {@link OCFile}.
  402. *
  403. * @param result {@link RemoteOperationResult} of an update on the edited {@link OCFile} sharing information.
  404. * @param file the edited {@link OCFile}
  405. */
  406. public void onUpdateShareInformation(RemoteOperationResult result, OCFile file) {
  407. this.file = file;
  408. if (result.isSuccess()) {
  409. refreshUiFromDB();
  410. } else {
  411. setupView();
  412. }
  413. }
  414. /**
  415. * Get {@link OCShare} instance from DB and updates the UI.
  416. */
  417. private void refreshUiFromDB() {
  418. // Updates UI with new state
  419. setupView();
  420. }
  421. @Override
  422. public void unshareWith(OCShare share) {
  423. fileOperationsHelper.unshareShare(file, share);
  424. }
  425. @Override
  426. public int updatePermissionsToShare(OCShare share,
  427. boolean canReshare,
  428. boolean canEdit,
  429. boolean canEditCreate,
  430. boolean canEditChange,
  431. boolean canEditDelete) {
  432. SharePermissionsBuilder spb = new SharePermissionsBuilder();
  433. spb.setSharePermission(canReshare);
  434. if (file.isFolder()) {
  435. spb.setUpdatePermission(canEditChange)
  436. .setCreatePermission(canEditCreate)
  437. .setDeletePermission(canEditDelete);
  438. } else {
  439. spb.setUpdatePermission(canEdit);
  440. }
  441. int permissions = spb.build();
  442. fileOperationsHelper.setPermissionsToShare(share, permissions);
  443. return permissions;
  444. }
  445. @Override
  446. public void updateNoteToShare(OCShare share, String note) {
  447. fileOperationsHelper.updateNoteToShare(share, note);
  448. }
  449. /**
  450. * Starts a dialog that requests a password to the user to protect a share link.
  451. *
  452. * @param createShare When 'true', the request for password will be followed by the creation of a new public
  453. * link; when 'false', a public share is assumed to exist, and the password is bound to it.
  454. * @param askForPassword if true, password is optional
  455. */
  456. public void requestPasswordForShareViaLink(boolean createShare, boolean askForPassword) {
  457. SharePasswordDialogFragment dialog = SharePasswordDialogFragment.newInstance(file,
  458. createShare,
  459. askForPassword);
  460. dialog.show(getChildFragmentManager(), SharePasswordDialogFragment.PASSWORD_FRAGMENT);
  461. }
  462. @Override
  463. public void requestPasswordForShare(OCShare share) {
  464. SharePasswordDialogFragment dialog = SharePasswordDialogFragment.newInstance(share);
  465. dialog.show(getChildFragmentManager(), SharePasswordDialogFragment.PASSWORD_FRAGMENT);
  466. }
  467. /**
  468. * Get known server capabilities from DB
  469. */
  470. public void refreshCapabilitiesFromDB() {
  471. capabilities = fileDataStorageManager.getCapability(user.getAccountName());
  472. }
  473. /**
  474. * Get public link from the DB to fill in the "Share link" section in the UI.
  475. *
  476. * Takes into account server capabilities before reading database.
  477. */
  478. public void refreshPublicShareFromDB() {
  479. if (FileDetailSharingFragmentHelper.isPublicShareDisabled(capabilities) || !file.canReshare()) {
  480. publicShareList.setVisibility(View.GONE);
  481. return;
  482. }
  483. // Get public share
  484. List<OCShare> shares = fileDataStorageManager.getSharesByPathAndType(file.getRemotePath(),
  485. ShareType.PUBLIC_LINK,
  486. "");
  487. if (shares.isEmpty()) {
  488. addPublicShare.setVisibility(View.VISIBLE);
  489. publicShareList.setVisibility(View.GONE);
  490. ImageView icon = requireView().findViewById(R.id.copy_internal_link_icon);
  491. icon.getBackground().setColorFilter(requireContext()
  492. .getResources()
  493. .getColor(R.color.primary_button_background_color),
  494. PorterDuff.Mode.SRC_IN);
  495. icon.getDrawable().mutate().setColorFilter(requireContext().getResources().getColor(R.color.black),
  496. PorterDuff.Mode.SRC_IN);
  497. requireView().findViewById(R.id.add_new_public_share_link).setOnClickListener(v -> createShareLink());
  498. } else {
  499. addPublicShare.setVisibility(View.GONE);
  500. publicShareList.setVisibility(View.VISIBLE);
  501. publicShareList.setAdapter(new PublicShareListAdapter(getContext(), shares, this));
  502. publicShareList.setLayoutManager(new LinearLayoutManager(getContext()));
  503. publicShareList.addItemDecoration(new SimpleListItemDividerDecoration(getContext()));
  504. }
  505. }
  506. @Override
  507. public void onSaveInstanceState(@NonNull Bundle outState) {
  508. super.onSaveInstanceState(outState);
  509. outState.putParcelable(ARG_FILE, file);
  510. outState.putParcelable(ARG_USER, user);
  511. }
  512. @Override
  513. public void avatarGenerated(Drawable avatarDrawable, Object callContext) {
  514. sharedWithYouAvatar.setImageDrawable(avatarDrawable);
  515. }
  516. @Override
  517. public boolean shouldCallGeneratedCallback(String tag, Object callContext) {
  518. return false;
  519. }
  520. }