FolderSyncAdapter.java 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. /**
  2. * Nextcloud Android client application
  3. *
  4. * @author Andy Scherzinger
  5. * Copyright (C) 2016 Andy Scherzinger
  6. * Copyright (C) 2016 Nextcloud
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
  10. * License as published by the Free Software Foundation; either
  11. * version 3 of the License, or any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
  17. *
  18. * You should have received a copy of the GNU Affero General Public
  19. * License along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. package com.owncloud.android.ui.adapter;
  22. import android.content.Context;
  23. import android.graphics.Bitmap;
  24. import android.support.v7.widget.RecyclerView;
  25. import android.view.LayoutInflater;
  26. import android.view.MotionEvent;
  27. import android.view.View;
  28. import android.view.ViewGroup;
  29. import android.widget.ImageButton;
  30. import android.widget.ImageView;
  31. import android.widget.LinearLayout;
  32. import android.widget.TextView;
  33. import android.widget.Toast;
  34. import com.afollestad.sectionedrecyclerview.SectionedRecyclerViewAdapter;
  35. import com.owncloud.android.R;
  36. import com.owncloud.android.datamodel.MediaFolder;
  37. import com.owncloud.android.datamodel.ThumbnailsCacheManager;
  38. import com.owncloud.android.lib.common.utils.Log_OC;
  39. import com.owncloud.android.utils.BitmapUtils;
  40. import com.owncloud.android.utils.MimetypeIconUtil;
  41. import java.io.File;
  42. import java.util.ArrayList;
  43. import java.util.List;
  44. /**
  45. * Adapter to display all auto-synced folders and/or instant upload media folders.
  46. */
  47. public class FolderSyncAdapter extends SectionedRecyclerViewAdapter<FolderSyncAdapter.MainViewHolder>
  48. implements View.OnClickListener, View.OnTouchListener {
  49. private static final String TAG = FolderSyncAdapter.class.getSimpleName();
  50. private final Context mContext;
  51. private final int mGridWidth;
  52. private final ClickListener mListener;
  53. private final List<MediaFolder> mMediaFolders;
  54. private final RecyclerView mRecyclerView;
  55. public FolderSyncAdapter(Context context, int gridWidth, ClickListener listener, RecyclerView recyclerView) {
  56. mContext = context;
  57. mGridWidth = gridWidth * 2;
  58. mListener = listener;
  59. mMediaFolders = new ArrayList<>();
  60. mRecyclerView = recyclerView;
  61. }
  62. public void setMediaFolders(List<MediaFolder> mediaFolders) {
  63. mMediaFolders.clear();
  64. mMediaFolders.addAll(mediaFolders);
  65. notifyDataSetChanged();
  66. }
  67. @Override
  68. public void onClick(View v) {
  69. }
  70. @Override
  71. public boolean onTouch(View v, MotionEvent event) {
  72. return false;
  73. }
  74. @Override
  75. public int getSectionCount() {
  76. return mMediaFolders.size();
  77. }
  78. @Override
  79. public int getItemCount(int section) {
  80. return mMediaFolders.get(section).filePaths.size();
  81. }
  82. @Override
  83. public void onBindHeaderViewHolder(MainViewHolder holder, int section) {
  84. final int sectionId = section;
  85. holder.title.setText(mMediaFolders.get(section).folder.substring(mMediaFolders.get(section).folder
  86. .lastIndexOf("/") + 1, mMediaFolders.get(section).folder.length()));
  87. holder.syncStatusButton.setVisibility(View.VISIBLE);
  88. holder.syncStatusButton.setTag(section);
  89. holder.syncStatusButton.setOnTouchListener(new View.OnTouchListener() {
  90. @Override
  91. public boolean onTouch(View v, MotionEvent event) {
  92. Toast.makeText(mContext, "Sync Status Clicked for " + mMediaFolders.get(sectionId).folder, Toast
  93. .LENGTH_SHORT)
  94. .show();
  95. return true;
  96. }
  97. });
  98. holder.menuButton.setVisibility(View.VISIBLE);
  99. holder.menuButton.setTag(section);
  100. holder.menuButton.setOnTouchListener(new View.OnTouchListener() {
  101. @Override
  102. public boolean onTouch(View v, MotionEvent event) {
  103. Toast.makeText(mContext, "Menu Clicked for " + mMediaFolders.get(sectionId).folder, Toast.LENGTH_SHORT)
  104. .show();
  105. return true;
  106. }
  107. });
  108. }
  109. @Override
  110. public void onBindViewHolder(MainViewHolder holder, int section, int relativePosition, int absolutePosition) {
  111. final Context c = holder.itemView.getContext();
  112. File file = new File(mMediaFolders.get(section).filePaths.get(relativePosition));
  113. /** Cancellation needs do be checked and done before changing the drawable in fileIcon, or
  114. * {@link ThumbnailsCacheManager#cancelPotentialThumbnailWork} will NEVER cancel any task.
  115. **/
  116. boolean allowedToCreateNewThumbnail = (ThumbnailsCacheManager.cancelPotentialThumbnailWork(file, holder.image));
  117. if (!file.isDirectory()) {
  118. holder.image.setImageResource(R.drawable.file);
  119. } else {
  120. holder.image.setImageResource(R.drawable.ic_menu_archive);
  121. }
  122. // set proper tag
  123. holder.image.setTag(file.hashCode());
  124. // get Thumbnail if file is image
  125. if (BitmapUtils.isImage(file)) {
  126. // Thumbnail in Cache?
  127. Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache(
  128. String.valueOf(file.hashCode())
  129. );
  130. if (thumbnail != null) {
  131. holder.image.setImageBitmap(thumbnail);
  132. } else {
  133. // generate new Thumbnail
  134. if (allowedToCreateNewThumbnail) {
  135. final ThumbnailsCacheManager.ThumbnailGenerationTask task =
  136. new ThumbnailsCacheManager.ThumbnailGenerationTask(holder.image);
  137. if (thumbnail == null) {
  138. if (BitmapUtils.isVideo(file)) {
  139. thumbnail = ThumbnailsCacheManager.mDefaultVideo;
  140. } else {
  141. thumbnail = ThumbnailsCacheManager.mDefaultImg;
  142. }
  143. }
  144. final ThumbnailsCacheManager.AsyncThumbnailDrawable asyncDrawable =
  145. new ThumbnailsCacheManager.AsyncThumbnailDrawable(
  146. mContext.getResources(),
  147. thumbnail,
  148. task
  149. );
  150. holder.image.setImageDrawable(asyncDrawable);
  151. task.execute(file);
  152. Log_OC.v(TAG, "Executing task to generate a new thumbnail");
  153. } // else, already being generated, don't restart it
  154. }
  155. } else {
  156. holder.image.setImageResource(MimetypeIconUtil.getFileTypeIconId(null, file.getName()));
  157. }
  158. if(mMediaFolders.get(section).numberOfFiles > 8 && relativePosition >= 8-1) {
  159. holder.counterValue.setText(Long.toString(mMediaFolders.get(section).numberOfFiles-8));
  160. holder.counterBar.setVisibility(View.VISIBLE);
  161. holder.thumbnailDarkener.setVisibility(View.VISIBLE);
  162. } else {
  163. holder.counterBar.setVisibility(View.GONE);
  164. holder.thumbnailDarkener.setVisibility(View.GONE);
  165. }
  166. //holder.itemView.setTag(String.format(Locale.getDefault(), "%d:%d:%d", section, relativePos, absolutePos));
  167. holder.itemView.setOnClickListener(this);
  168. }
  169. @Override
  170. public MainViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
  171. View v = LayoutInflater.from(parent.getContext()).inflate(
  172. viewType == VIEW_TYPE_HEADER ?
  173. R.layout.folder_sync_item_header : R.layout.grid_sync_item, parent, false);
  174. return new MainViewHolder(v);
  175. }
  176. public interface ClickListener {
  177. void onClick(View view, int section, int relative, int absolute);
  178. }
  179. static class MainViewHolder extends RecyclerView.ViewHolder {
  180. final ImageView image;
  181. final TextView title;
  182. final ImageButton menuButton;
  183. final ImageButton syncStatusButton;
  184. final LinearLayout counterBar;
  185. final TextView counterValue;
  186. final ImageView thumbnailDarkener;
  187. public MainViewHolder(View itemView) {
  188. super(itemView);
  189. image = (ImageView) itemView.findViewById(R.id.thumbnail);
  190. title = (TextView) itemView.findViewById(R.id.title);
  191. menuButton = (ImageButton) itemView.findViewById(R.id.settingsButton);
  192. syncStatusButton = (ImageButton) itemView.findViewById(R.id.syncStatusButton);
  193. counterBar = (LinearLayout) itemView.findViewById(R.id.counterLayout);
  194. counterValue = (TextView) itemView.findViewById(R.id.counter);
  195. thumbnailDarkener = (ImageView) itemView.findViewById(R.id.thumbnailDarkener);
  196. }
  197. }
  198. }