add RecommendedFilesAdapter

Signed-off-by: alperozturk <alper_ozturk@proton.me>
This commit is contained in:
alperozturk 2024-12-13 15:47:46 +01:00 committed by Alper Öztürk
parent 878d8accf9
commit 6e92a5aab7
4 changed files with 209 additions and 1 deletions

View file

@ -82,6 +82,7 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
@ -97,6 +98,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import me.zhanghai.android.fastscroll.PopupTextProvider; import me.zhanghai.android.fastscroll.PopupTextProvider;
@ -433,6 +435,67 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
} else if (holder instanceof OCFileListHeaderViewHolder headerViewHolder) { } else if (holder instanceof OCFileListHeaderViewHolder headerViewHolder) {
String text = currentDirectory.getRichWorkspace(); String text = currentDirectory.getRichWorkspace();
final var recommendedFiles = headerViewHolder.getBinding().recommendedFilesRecyclerView;
final LinearLayoutManager layoutManager = new LinearLayoutManager(activity, LinearLayoutManager.HORIZONTAL, false);
recommendedFiles.setLayoutManager(layoutManager);
// TODO use actual data
ArrayList<Recommendation> mockData = new ArrayList<>(Arrays.asList(
new Recommendation(
1L,
System.currentTimeMillis(),
"Document1",
"/documents",
"pdf",
"application/pdf",
true,
"Recently opened"
),
new Recommendation(
2L,
System.currentTimeMillis() - 3600000,
"Image1",
"/pictures",
"jpg",
"image/jpeg",
true,
"Frequently viewed"
),
new Recommendation(
3L,
System.currentTimeMillis() - 7200000,
"Presentation1",
"/presentations",
"pptx",
"application/vnd.ms-powerpoint",
false,
"Shared with you"
),
new Recommendation(
4L,
System.currentTimeMillis() - 86400000,
"Video1",
"/videos",
"mp4",
"video/mp4",
true,
"Recent download"
),
new Recommendation(
5L,
System.currentTimeMillis() - 604800000,
"Spreadsheet1",
"/spreadsheets",
"xlsx",
"application/vnd.ms-excel",
false,
"Marked as important"
)));
final var adapter = new RecommendedFilesAdapter(activity, viewThemeUtils, mockData);
recommendedFiles.setAdapter(adapter);
PreviewTextFragment.setText(headerViewHolder.getHeaderText(), text, null, activity, true, true, viewThemeUtils); PreviewTextFragment.setText(headerViewHolder.getHeaderText(), text, null, activity, true, true, viewThemeUtils);
headerViewHolder.getHeaderView().setOnClickListener(v -> ocFileListFragmentInterface.onHeaderClicked()); headerViewHolder.getHeaderView().setOnClickListener(v -> ocFileListFragmentInterface.onHeaderClicked());
} else { } else {
@ -766,11 +829,13 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
return false; return false;
} }
// TODO add or condition for recommended files
if (currentDirectory.getRichWorkspace() == null) { if (currentDirectory.getRichWorkspace() == null) {
return false; return false;
} }
return !TextUtils.isEmpty(currentDirectory.getRichWorkspace().trim()); return !TextUtils.isEmpty(currentDirectory.getRichWorkspace().trim()) || true;
} }
/** /**

View file

@ -0,0 +1,96 @@
/*
* Nextcloud - Android Client
*
* SPDX-FileCopyrightText: 2024 Alper Ozturk <alper.ozturk@nextcloud.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
package com.owncloud.android.ui.adapter
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.content.res.ResourcesCompat
import androidx.recyclerview.widget.RecyclerView
import com.owncloud.android.R
import com.owncloud.android.databinding.RecommendedFilesListItemBinding
import com.owncloud.android.utils.BitmapUtils
import com.owncloud.android.utils.DisplayUtils
import com.owncloud.android.utils.MimeTypeUtil
import com.owncloud.android.utils.theme.ViewThemeUtils
// TODO delete mock data
data class Recommendation(
val id: Long,
val timestamp: Long,
val name: String,
val directory: String,
val extension: String,
val mimeType: String,
val hasPreview: Boolean,
val reason: String
)
class RecommendedFilesAdapter(
private val context: Context,
private val viewThemeUtils: ViewThemeUtils,
private val recommendations: List<Recommendation>
) : RecyclerView.Adapter<RecommendedFilesAdapter.RecommendedFilesViewHolder>() {
inner class RecommendedFilesViewHolder(val binding: RecommendedFilesListItemBinding) :
RecyclerView.ViewHolder(binding.root) {
init {
binding.root.setOnClickListener {
val position = bindingAdapterPosition
if (position != RecyclerView.NO_POSITION) {
// TODO onclick item
}
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecommendedFilesViewHolder {
val binding = RecommendedFilesListItemBinding
.inflate(LayoutInflater.from(parent.context), parent, false)
return RecommendedFilesViewHolder(binding)
}
override fun getItemCount(): Int = recommendations.size
override fun onBindViewHolder(holder: RecommendedFilesViewHolder, position: Int) {
val item = recommendations[position]
holder.binding.name.text = item.name
holder.binding.timestamp.text = DisplayUtils.getRelativeTimestamp(context, item.timestamp)
val thumbnail = getThumbnail(item)
holder.binding.icon.setImageBitmap(thumbnail)
}
private fun getThumbnail(item: Recommendation): Bitmap {
var drawable = MimeTypeUtil.getFileTypeIcon(
item.mimeType,
item.name,
context,
viewThemeUtils
)
if (drawable == null) {
drawable = ResourcesCompat.getDrawable(
context.resources,
R.drawable.file_image,
null
)
}
if (drawable == null) {
drawable = ColorDrawable(Color.GRAY)
}
val width = DisplayUtils.convertPixelToDp(40, context).toInt()
return BitmapUtils.drawableToBitmap(drawable, width / 2, width / 2)
}
}

View file

@ -29,4 +29,10 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:contentDescription="@null" android:contentDescription="@null"
android:src="@drawable/preview_markdown_gradient_shape" /> android:src="@drawable/preview_markdown_gradient_shape" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recommended_files_recycler_view"
android:layout_gravity="bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</FrameLayout> </FrameLayout>

View file

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Nextcloud - Android Client
~
~ SPDX-FileCopyrightText: 2024 Alper Ozturk <alper.ozturk@nextcloud.com>
~ SPDX-License-Identifier: AGPL-3.0-or-later
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="@dimen/standard_padding"
android:gravity="center_vertical">
<ImageView
android:id="@+id/icon"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginEnd="8dp"
android:contentDescription="@string/preview_image_description"
android:src="@drawable/preview_image_gradient_shape" />
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:textSize="16sp"
android:textColor="@color/text_color"
android:ellipsize="end"
android:maxLines="1"/>
<TextView
android:id="@+id/timestamp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12sp"
android:textColor="@color/text_color"
android:layout_marginStart="8dp" />
</LinearLayout>