Fix merge conflict

Signed-off-by: alperozturk <alper_ozturk@proton.me>
This commit is contained in:
alperozturk 2023-12-06 15:27:48 +01:00
commit 2f1e3ea2b4
No known key found for this signature in database
GPG key ID: 4E577DC593B59BDF
47 changed files with 533 additions and 484 deletions

View file

@ -21,7 +21,7 @@ jobs:
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v3
- name: set up JDK 17
uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3
uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v3
with:
distribution: "temurin"
java-version: 17

View file

@ -21,7 +21,7 @@ jobs:
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v3
- name: Set up JDK 17
uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3
uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v3
with:
distribution: "temurin"
java-version: 17

View file

@ -18,7 +18,7 @@ jobs:
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v3
- name: Set up JDK 17
uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3
uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v3
with:
distribution: "temurin"
java-version: 17

View file

@ -22,7 +22,7 @@ jobs:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v3
if: ${{ steps.check-secrets.outputs.ok == 'true' }}
- name: set up JDK 17
uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3
uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v3
if: ${{ steps.check-secrets.outputs.ok == 'true' }}
with:
distribution: "temurin"

View file

@ -40,7 +40,7 @@ jobs:
~/.android/adb*
key: avd-${{ matrix.api-level }}
- uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3
- uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v3
with:
distribution: "temurin"
java-version: 17

View file

@ -20,7 +20,7 @@ jobs:
steps:
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Set up JDK 17
uses: actions/setup-java@0ab4596768b603586c0de567f2430c30f5b0d2b0 # v3.13.0
uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4.0.0
with:
distribution: "temurin"
java-version: 17

View file

@ -126,6 +126,10 @@ android {
}
}
buildFeatures {
buildConfig = true
}
productFlavors {
// used for f-droid
generic {

View file

@ -169,6 +169,9 @@
<receiver
android:name="com.nextcloud.client.jobs.NotificationWork$NotificationReceiver"
android:exported="false" />
<receiver
android:name="com.owncloud.android.files.services.FileUploader$UploadNotificationActionReceiver"
android:exported="false" />
<receiver
android:name="com.nextcloud.client.widget.DashboardWidgetProvider"
android:exported="false">

View file

@ -43,6 +43,7 @@ import com.owncloud.android.datamodel.FileDataStorageManager
import com.owncloud.android.datamodel.ThumbnailsCacheManager
import com.owncloud.android.datamodel.UploadsStorageManager
import com.owncloud.android.db.OCUpload
import com.owncloud.android.files.services.FileUploader
import com.owncloud.android.lib.common.OwnCloudAccount
import com.owncloud.android.lib.common.OwnCloudClientManagerFactory
import com.owncloud.android.lib.common.network.OnDatatransferProgressListener
@ -197,6 +198,18 @@ class FilesUploadWorker(
* adapted from [com.owncloud.android.files.services.FileUploader.notifyUploadStart]
*/
private fun createNotification(uploadFileOperation: UploadFileOperation) {
val notificationActionIntent = Intent(context, FileUploader.UploadNotificationActionReceiver::class.java)
notificationActionIntent.putExtra(FileUploader.EXTRA_ACCOUNT_NAME, uploadFileOperation.user.accountName)
notificationActionIntent.putExtra(FileUploader.EXTRA_REMOTE_PATH, uploadFileOperation.remotePath)
notificationActionIntent.action = FileUploader.ACTION_CANCEL_BROADCAST
val pendingIntent = PendingIntent.getBroadcast(
context,
SecureRandom().nextInt(),
notificationActionIntent,
PendingIntent.FLAG_IMMUTABLE
)
notificationBuilder
.setOngoing(true)
.setSmallIcon(R.drawable.notification_icon)
@ -209,6 +222,8 @@ class FilesUploadWorker(
uploadFileOperation.fileName
)
)
.clearActions() // to make sure there is only one action
.addAction(R.drawable.ic_action_cancel_grey, context.getString(R.string.common_cancel), pendingIntent)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
notificationBuilder.setChannelId(NotificationUtils.NOTIFICATION_CHANNEL_UPLOAD)
@ -275,6 +290,7 @@ class FilesUploadWorker(
.setAutoCancel(true)
.setOngoing(false)
.setProgress(0, 0, false)
.clearActions()
val content = ErrorMessageAdapter.getErrorCauseMessage(uploadResult, uploadFileOperation, context.resources)

View file

@ -86,7 +86,7 @@ class StackRemoteViewsFactory(
val userAccountManager: UserAccountManager,
val clientFactory: ClientFactory,
val intent: Intent,
val widgetRepository: WidgetRepository
private val widgetRepository: WidgetRepository
) : RemoteViewsService.RemoteViewsFactory {
private lateinit var widgetConfiguration: WidgetConfiguration
@ -163,58 +163,20 @@ class StackRemoteViewsFactory(
// we will switch soon to coil and then streamline all of this
// Kotlin cannot catch multiple exception types at same time
@Suppress("NestedBlockDepth", "TooGenericExceptionCaught")
@Suppress("NestedBlockDepth")
private fun createItemView(position: Int): RemoteViews {
return RemoteViews(context.packageName, R.layout.widget_item).apply {
if (widgetItems.isEmpty()) {
return@apply
}
val widgetItem = widgetItems[position]
// icon bitmap/svg
if (widgetItem.iconUrl.isNotEmpty()) {
val glide: FutureTarget<Bitmap>
if (Uri.parse(widgetItem.iconUrl).encodedPath!!.endsWith(".svg")) {
glide = Glide.with(context)
.using(
CustomGlideUriLoader(userAccountManager.user, clientFactory),
InputStream::class.java
)
.from(Uri::class.java)
.`as`(SVGorImage::class.java)
.transcode(SvgOrImageBitmapTranscoder(SVG_SIZE, SVG_SIZE), Bitmap::class.java)
.sourceEncoder(StreamEncoder())
.cacheDecoder(FileToStreamDecoder(SvgOrImageDecoder()))
.decoder(SvgOrImageDecoder())
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.load(Uri.parse(widgetItem.iconUrl))
.into(SVG_SIZE, SVG_SIZE)
} else {
glide = Glide.with(context)
.using(CustomGlideStreamLoader(widgetConfiguration.user.get(), clientFactory))
.load(widgetItem.iconUrl)
.asBitmap()
.into(SVG_SIZE, SVG_SIZE)
}
try {
if (widgetConfiguration.roundIcon) {
setImageViewBitmap(R.id.icon, BitmapUtils.roundBitmap(glide.get()))
} else {
setImageViewBitmap(R.id.icon, glide.get())
}
} catch (e: Exception) {
Log_OC.d(TAG, "Error setting icon", e)
setImageViewResource(R.id.icon, R.drawable.ic_dashboard)
}
loadIcon(widgetItem, this)
}
// text
setTextViewText(R.id.title, widgetItem.title)
if (widgetItem.subtitle.isNotEmpty()) {
setViewVisibility(R.id.subtitle, View.VISIBLE)
setTextViewText(R.id.subtitle, widgetItem.subtitle)
} else {
setViewVisibility(R.id.subtitle, View.GONE)
}
updateTexts(widgetItem, this)
if (widgetItem.link.isNotEmpty()) {
val clickIntent = Intent(Intent.ACTION_VIEW, Uri.parse(widgetItem.link))
@ -223,6 +185,65 @@ class StackRemoteViewsFactory(
}
}
@Suppress("TooGenericExceptionCaught")
private fun loadIcon(widgetItem: DashboardWidgetItem, remoteViews: RemoteViews) {
val isIconSVG = Uri.parse(widgetItem.iconUrl).encodedPath!!.endsWith(".svg")
val source: FutureTarget<Bitmap> = if (isIconSVG) {
loadSVGIcon(widgetItem)
} else {
loadBitmapIcon(widgetItem)
}
try {
val bitmap: Bitmap = if (widgetConfiguration.roundIcon) {
BitmapUtils.roundBitmap(source.get())
} else {
source.get()
}
remoteViews.setImageViewBitmap(R.id.icon, bitmap)
} catch (e: Exception) {
Log_OC.d(TAG, "Error setting icon", e)
remoteViews.setImageViewResource(R.id.icon, R.drawable.ic_dashboard)
}
}
private fun loadSVGIcon(widgetItem: DashboardWidgetItem): FutureTarget<Bitmap> {
return Glide.with(context)
.using(
CustomGlideUriLoader(userAccountManager.user, clientFactory),
InputStream::class.java
)
.from(Uri::class.java)
.`as`(SVGorImage::class.java)
.transcode(SvgOrImageBitmapTranscoder(SVG_SIZE, SVG_SIZE), Bitmap::class.java)
.sourceEncoder(StreamEncoder())
.cacheDecoder(FileToStreamDecoder(SvgOrImageDecoder()))
.decoder(SvgOrImageDecoder())
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.load(Uri.parse(widgetItem.iconUrl))
.into(SVG_SIZE, SVG_SIZE)
}
private fun loadBitmapIcon(widgetItem: DashboardWidgetItem): FutureTarget<Bitmap> {
return Glide.with(context)
.using(CustomGlideStreamLoader(widgetConfiguration.user.get(), clientFactory))
.load(widgetItem.iconUrl)
.asBitmap()
.into(SVG_SIZE, SVG_SIZE)
}
private fun updateTexts(widgetItem: DashboardWidgetItem, remoteViews: RemoteViews) {
remoteViews.setTextViewText(R.id.title, widgetItem.title)
if (widgetItem.subtitle.isNotEmpty()) {
remoteViews.setViewVisibility(R.id.subtitle, View.VISIBLE)
remoteViews.setTextViewText(R.id.subtitle, widgetItem.subtitle)
} else {
remoteViews.setViewVisibility(R.id.subtitle, View.GONE)
}
}
override fun getLoadingView(): RemoteViews? {
return null
}

View file

@ -83,6 +83,7 @@ import java.util.Vector;
import javax.inject.Inject;
import androidx.core.app.NotificationCompat;
import androidx.core.app.ServiceCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import dagger.android.AndroidInjection;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
@ -203,7 +204,11 @@ public class FileDownloader extends Service
Log_OC.d(TAG, "Starting command with id " + startId);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
startForeground(FOREGROUND_SERVICE_ID, mNotification, ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC);
ServiceCompat.startForeground(
this,
FOREGROUND_SERVICE_ID,
mNotification,
ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC);
} else {
startForeground(FOREGROUND_SERVICE_ID, mNotification);
}

View file

@ -34,6 +34,7 @@ import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ServiceInfo;
@ -128,6 +129,10 @@ public class FileUploader extends Service
public static final String EXTRA_LINKED_TO_PATH = "LINKED_TO";
public static final String ACCOUNT_NAME = "ACCOUNT_NAME";
public static final String EXTRA_ACCOUNT_NAME = "ACCOUNT_NAME";
public static final String ACTION_CANCEL_BROADCAST = "CANCEL";
public static final String ACTION_PAUSE_BROADCAST = "PAUSE";
private static final int FOREGROUND_SERVICE_ID = 411;
public static final String KEY_FILE = "FILE";
@ -198,11 +203,13 @@ public class FileUploader extends Service
private Notification mNotification;
private Looper mServiceLooper;
private ServiceHandler mServiceHandler;
private IBinder mBinder;
private static IBinder mBinder;
private OwnCloudClient mUploadClient;
private Account mCurrentAccount;
private FileDataStorageManager mStorageManager;
private SecureRandom secureRandomGenerator = new SecureRandom();
@Inject UserAccountManager accountManager;
@Inject UploadsStorageManager mUploadsStorageManager;
@Inject ConnectivityService connectivityService;
@ -233,6 +240,7 @@ public class FileUploader extends Service
/**
* Service initialization
*/
@SuppressFBWarnings("ST")
@Override
public void onCreate() {
super.onCreate();
@ -280,6 +288,7 @@ public class FileUploader extends Service
/**
* Service clean up
*/
@SuppressFBWarnings("ST")
@Override
public void onDestroy() {
Log_OC.v(TAG, "Destroying service");
@ -708,6 +717,12 @@ public class FileUploader extends Service
*/
private void notifyUploadStart(UploadFileOperation upload) {
// / create status notification with a progress bar
Intent notificationActionIntent = new Intent(getApplicationContext(),UploadNotificationActionReceiver.class);
notificationActionIntent.putExtra(EXTRA_ACCOUNT_NAME,upload.getUser().getAccountName());
notificationActionIntent.putExtra(EXTRA_REMOTE_PATH,upload.getRemotePath());
notificationActionIntent.setAction(ACTION_CANCEL_BROADCAST);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(),secureRandomGenerator.nextInt(),notificationActionIntent, PendingIntent.FLAG_IMMUTABLE);
mLastPercent = 0;
mNotificationBuilder = NotificationUtils.newNotificationBuilder(this, viewThemeUtils);
mNotificationBuilder
@ -718,7 +733,10 @@ public class FileUploader extends Service
.setProgress(100, 0, false)
.setContentText(
String.format(getString(R.string.uploader_upload_in_progress_content), 0, upload.getFileName())
);
)
.clearActions() // to make sure there is only one action
.addAction(R.drawable.ic_action_cancel_grey,getApplicationContext().getString(R.string.common_cancel),pendingIntent);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mNotificationBuilder.setChannelId(NotificationUtils.NOTIFICATION_CHANNEL_UPLOAD);
@ -811,7 +829,8 @@ public class FileUploader extends Service
.setContentTitle(getString(tickerId))
.setAutoCancel(true)
.setOngoing(false)
.setProgress(0, 0, false);
.setProgress(0, 0, false)
.clearActions();
content = ErrorMessageAdapter.getErrorCauseMessage(uploadResult, upload, getResources());
@ -859,7 +878,7 @@ public class FileUploader extends Service
mNotificationBuilder.setContentText(content);
if (!uploadResult.isSuccess()) {
mNotificationManager.notify((new SecureRandom()).nextInt(), mNotificationBuilder.build());
mNotificationManager.notify(secureRandomGenerator.nextInt(), mNotificationBuilder.build());
}
}
}
@ -1408,4 +1427,32 @@ public class FileUploader extends Service
mService.stopSelf(msg.arg1);
}
}
/**
* When cancel action in upload notification is pressed, cancel upload of item
*/
public static class UploadNotificationActionReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String accountName = intent.getStringExtra(EXTRA_ACCOUNT_NAME);
String remotePath = intent.getStringExtra(EXTRA_REMOTE_PATH);
String action = intent.getAction();
if (ACTION_CANCEL_BROADCAST.equals(action)) {
Log_OC.d(TAG, "Cancel broadcast received for file " + remotePath + " at " + System.currentTimeMillis());
if (accountName == null || remotePath == null) return;
FileUploaderBinder uploadBinder = (FileUploaderBinder) mBinder;
uploadBinder.cancel(accountName, remotePath, null);
}else if(ACTION_PAUSE_BROADCAST.equals(action)){
} else {
Log_OC.d(TAG, "Unknown action to perform as UploadNotificationActionReceiver.");
}
}
}
}

View file

@ -350,14 +350,18 @@ public class FileDisplayActivity extends FileActivity
public void onConfigurationChanged(@NonNull Configuration newConfig) {
super.onConfigurationChanged(newConfig);
StoragePermissionDialogFragment fragment = (StoragePermissionDialogFragment) getSupportFragmentManager().findFragmentByTag(PERMISSION_CHOICE_DIALOG_TAG);
if (fragment != null) {
Dialog dialog = fragment.getDialog();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
StoragePermissionDialogFragment fragment =
(StoragePermissionDialogFragment) getSupportFragmentManager()
.findFragmentByTag(PERMISSION_CHOICE_DIALOG_TAG);
if (fragment != null) {
Dialog dialog = fragment.getDialog();
if (dialog != null && dialog.isShowing()) {
dialog.dismiss();
getSupportFragmentManager().beginTransaction().remove(fragment).commitNowAllowingStateLoss();
PermissionUtil.requestExternalStoragePermission(this, viewThemeUtils);
if (dialog != null && dialog.isShowing()) {
dialog.dismiss();
getSupportFragmentManager().beginTransaction().remove(fragment).commitNowAllowingStateLoss();
PermissionUtil.requestExternalStoragePermission(this, viewThemeUtils);
}
}
}
}

View file

@ -41,10 +41,21 @@ import android.os.Looper;
import android.os.Parcelable;
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.view.*;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager.LayoutParams;
import android.widget.*;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.material.button.MaterialButton;
import com.nextcloud.client.account.User;
@ -66,13 +77,21 @@ import com.owncloud.android.operations.CreateFolderOperation;
import com.owncloud.android.operations.RefreshFolderOperation;
import com.owncloud.android.operations.UploadFileOperation;
import com.owncloud.android.syncadapter.FileSyncAdapter;
import com.owncloud.android.ui.adapter.UploaderAdapter;
import com.owncloud.android.ui.adapter.ReceiveExternalFilesAdapter;
import com.owncloud.android.ui.asynctasks.CopyAndUploadContentUrisTask;
import com.owncloud.android.ui.dialog.*;
import com.owncloud.android.ui.dialog.AccountChooserInterface;
import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
import com.owncloud.android.ui.dialog.CreateFolderDialogFragment;
import com.owncloud.android.ui.dialog.MultipleAccountsDialog;
import com.owncloud.android.ui.dialog.SortingOrderDialogFragment;
import com.owncloud.android.ui.fragment.TaskRetainerFragment;
import com.owncloud.android.ui.helpers.FileOperationsHelper;
import com.owncloud.android.ui.helpers.UriUploader;
import com.owncloud.android.utils.*;
import com.owncloud.android.utils.DataHolderUtil;
import com.owncloud.android.utils.DisplayUtils;
import com.owncloud.android.utils.ErrorMessageAdapter;
import com.owncloud.android.utils.FileSortOrder;
import com.owncloud.android.utils.MimeType;
import com.owncloud.android.utils.theme.ViewThemeUtils;
import java.io.File;
@ -80,7 +99,12 @@ import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Method;
import java.nio.charset.Charset;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
import java.util.Stack;
import java.util.Vector;
import javax.inject.Inject;
@ -96,6 +120,7 @@ import androidx.core.view.MenuItemCompat;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentManager;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import static com.owncloud.android.utils.DisplayUtils.openSortingOrderDialogFragment;
@ -103,8 +128,8 @@ import static com.owncloud.android.utils.DisplayUtils.openSortingOrderDialogFrag
* This can be used to upload things to an ownCloud instance.
*/
public class ReceiveExternalFilesActivity extends FileActivity
implements OnItemClickListener, View.OnClickListener, CopyAndUploadContentUrisTask.OnCopyTmpFilesTaskListener,
SortingOrderDialogFragment.OnSortingOrderListener, Injectable, AccountChooserInterface {
implements View.OnClickListener, CopyAndUploadContentUrisTask.OnCopyTmpFilesTaskListener,
SortingOrderDialogFragment.OnSortingOrderListener, Injectable, AccountChooserInterface, ReceiveExternalFilesAdapter.OnItemClickListener {
private static final String TAG = ReceiveExternalFilesActivity.class.getSimpleName();
@ -125,6 +150,7 @@ public class ReceiveExternalFilesActivity extends FileActivity
private OCFile mFile;
private SyncBroadcastReceiver mSyncBroadcastReceiver;
private ReceiveExternalFilesAdapter receiveExternalFilesAdapter;
private boolean mSyncInProgress;
private final static int REQUEST_CODE__SETUP_ACCOUNT = REQUEST_CODE__LAST_SHARED + 1;
@ -273,6 +299,22 @@ public class ReceiveExternalFilesActivity extends FileActivity
populateDirectoryList();
}
@Override
public void selectFile(OCFile file) {
if (file.isFolder()) {
if (file.isEncrypted() &&
!FileOperationsHelper.isEndToEndEncryptionSetup(this, getUser().orElseThrow(IllegalAccessError::new))) {
DisplayUtils.showSnackMessage(this, R.string.e2e_not_yet_setup);
return;
}
startSyncFolderOperation(file);
mParents.push(file.getFileName());
populateDirectoryList();
}
}
public static class DialogNoAccount extends DialogFragment {
@NonNull
@Override
@ -611,39 +653,6 @@ public class ReceiveExternalFilesActivity extends FileActivity
}
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// click on folder in the list
Log_OC.d(TAG, "on item click");
List<OCFile> tmpFiles = getStorageManager().getFolderContent(mFile, false);
tmpFiles = sortFileList(tmpFiles);
if (tmpFiles.isEmpty()) {
return;
}
// filter on dirtype
Vector<OCFile> files = new Vector<>();
files.addAll(tmpFiles);
if (files.size() < position) {
throw new IndexOutOfBoundsException("Incorrect item selected");
}
OCFile ocFile = files.get(position);
if (ocFile.isFolder()) {
if (ocFile.isEncrypted() &&
!FileOperationsHelper.isEndToEndEncryptionSetup(this, getUser().orElseThrow(IllegalAccessError::new))) {
DisplayUtils.showSnackMessage(this, R.string.e2e_not_yet_setup);
return;
}
OCFile folderToEnter = files.get(position);
startSyncFolderOperation(folderToEnter);
mParents.push(folderToEnter.getFileName());
populateDirectoryList();
}
}
@Override
public void onClick(View v) {
// click on button
@ -740,29 +749,10 @@ public class ReceiveExternalFilesActivity extends FileActivity
binding.list.setVisibility(View.GONE);
} else {
mEmptyListContainer.setVisibility(View.GONE);
files = sortFileList(files);
List<Map<String, Object>> data = new LinkedList<>();
for (OCFile f : files) {
Map<String, Object> h = new HashMap<>();
h.put("dirname", f);
data.add(h);
}
UploaderAdapter sa = new UploaderAdapter(this,
data,
R.layout.uploader_list_item_layout,
new String[]{"dirname"},
new int[]{R.id.filename},
getStorageManager(),
getUser().get(),
syncedFolderProvider,
viewThemeUtils);
binding.list.setAdapter(sa);
binding.list.setVisibility(View.VISIBLE);
setupReceiveExternalFilesAdapter(files);
}
MaterialButton btnChooseFolder = binding.uploaderChooseFolder;
viewThemeUtils.material.colorMaterialButtonPrimaryFilled(btnChooseFolder);
btnChooseFolder.setOnClickListener(this);
@ -774,8 +764,6 @@ public class ReceiveExternalFilesActivity extends FileActivity
viewThemeUtils.material.colorMaterialButtonPrimaryOutlined(binding.uploaderCancel);
binding.uploaderCancel.setOnClickListener(this);
binding.list.setOnItemClickListener(this);
sortButton = binding.toolbarLayout.sortButton;
FileSortOrder sortOrder = preferences.getSortOrderByFolder(mFile);
sortButton.setText(DisplayUtils.getSortOrderStringId(sortOrder));
@ -783,6 +771,21 @@ public class ReceiveExternalFilesActivity extends FileActivity
}
}
private void setupReceiveExternalFilesAdapter(List<OCFile> files) {
receiveExternalFilesAdapter = new ReceiveExternalFilesAdapter(files,
this,
getUser().get(),
getStorageManager(),
viewThemeUtils,
syncedFolderProvider,
this);
binding.list.setLayoutManager(new LinearLayoutManager(this));
binding.list.setAdapter(receiveExternalFilesAdapter);
binding.list.setVisibility(View.VISIBLE);
}
protected void setupEmptyList() {
mEmptyListContainer = binding.emptyView.emptyListView;
mEmptyListMessage = binding.emptyView.emptyListViewText;
@ -1016,19 +1019,35 @@ public class ReceiveExternalFilesActivity extends FileActivity
menu.findItem(R.id.action_create_dir).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
}
// tint search event
final MenuItem searchMenuItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchMenuItem);
setupSearchView(menu);
MenuItem newFolderMenuItem = menu.findItem(R.id.action_create_dir);
newFolderMenuItem.setEnabled(mFile.canWrite());
// hacky as no default way is provided
viewThemeUtils.androidx.themeToolbarSearchView(searchView);
return true;
}
private void setupSearchView(Menu menu) {
final MenuItem searchMenuItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchMenuItem);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
receiveExternalFilesAdapter.filter(query);
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
receiveExternalFilesAdapter.filter(newText);
return false;
}
});
viewThemeUtils.androidx.themeToolbarSearchView(searchView);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
boolean retval = true;

View file

@ -0,0 +1,176 @@
/*
* Nextcloud Android client application
*
* @author Alper Ozturk
* Copyright (C) 2023 Alper Ozturk
* Copyright (C) 2023 Nextcloud GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.owncloud.android.ui.adapter
import android.annotation.SuppressLint
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.recyclerview.widget.RecyclerView
import com.nextcloud.client.account.User
import com.owncloud.android.databinding.UploaderListItemLayoutBinding
import com.owncloud.android.datamodel.FileDataStorageManager
import com.owncloud.android.datamodel.OCFile
import com.owncloud.android.datamodel.SyncedFolderProvider
import com.owncloud.android.datamodel.ThumbnailsCacheManager
import com.owncloud.android.datamodel.ThumbnailsCacheManager.AsyncThumbnailDrawable
import com.owncloud.android.datamodel.ThumbnailsCacheManager.ThumbnailGenerationTask
import com.owncloud.android.datamodel.ThumbnailsCacheManager.ThumbnailGenerationTaskObject
import com.owncloud.android.utils.DisplayUtils
import com.owncloud.android.utils.MimeTypeUtil
import com.owncloud.android.utils.theme.ViewThemeUtils
@Suppress("LongParameterList")
class ReceiveExternalFilesAdapter(
private val files: List<OCFile>,
private val context: Context,
private val user: User,
private val storageManager: FileDataStorageManager,
private val viewThemeUtils: ViewThemeUtils,
private val syncedFolderProvider: SyncedFolderProvider,
private val onItemClickListener: OnItemClickListener
) : RecyclerView.Adapter<ReceiveExternalFilesAdapter.ReceiveExternalViewHolder>() {
private var filteredFiles: List<OCFile> = files
interface OnItemClickListener {
fun selectFile(file: OCFile)
}
inner class ReceiveExternalViewHolder(val binding: UploaderListItemLayoutBinding) :
RecyclerView.ViewHolder(binding.root) {
init {
binding.root.setOnClickListener {
val position = bindingAdapterPosition
if (position != RecyclerView.NO_POSITION) {
onItemClickListener.selectFile(filteredFiles[position])
}
}
}
}
@SuppressLint("NotifyDataSetChanged")
fun filter(query: String) {
filteredFiles = if (query.isEmpty()) {
files
} else {
files.filter { file ->
file.fileName.contains(query, ignoreCase = true)
}
}
notifyDataSetChanged()
}
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ReceiveExternalViewHolder {
val binding = UploaderListItemLayoutBinding
.inflate(LayoutInflater.from(viewGroup.context), viewGroup, false)
return ReceiveExternalViewHolder(binding)
}
override fun onBindViewHolder(viewHolder: ReceiveExternalViewHolder, position: Int) {
val file = filteredFiles[position]
viewHolder.binding.filename.text = file.fileName
viewHolder.binding.lastMod.text = DisplayUtils.getRelativeTimestamp(context, file.modificationTimestamp)
if (!file.isFolder) {
viewHolder.binding.fileSize.text = DisplayUtils.bytesToHumanReadable(file.fileLength)
}
viewHolder.binding.fileSize.visibility = if (file.isFolder) {
View.GONE
} else {
View.VISIBLE
}
viewHolder.binding.fileSeparator.visibility = if (file.isFolder) {
View.GONE
} else {
View.VISIBLE
}
val thumbnailImageView = viewHolder.binding.thumbnail
setupThumbnail(thumbnailImageView, file)
}
private fun setupThumbnail(thumbnailImageView: ImageView, file: OCFile) {
thumbnailImageView.tag = file.fileId
if (file.isFolder) {
setupThumbnailForFolder(thumbnailImageView, file)
} else if (MimeTypeUtil.isImage(file) && file.remoteId != null) {
setupThumbnailForImage(thumbnailImageView, file)
} else {
setupDefaultThumbnail(thumbnailImageView, file)
}
}
private fun setupThumbnailForFolder(thumbnailImageView: ImageView, file: OCFile) {
val isAutoUploadFolder = SyncedFolderProvider.isAutoUploadFolder(syncedFolderProvider, file, user)
val isDarkModeActive = syncedFolderProvider.preferences.isDarkModeEnabled
val overlayIconId = file.getFileOverlayIconId(isAutoUploadFolder)
val icon = MimeTypeUtil.getFileIcon(isDarkModeActive, overlayIconId, context, viewThemeUtils)
thumbnailImageView.setImageDrawable(icon)
}
@Suppress("NestedBlockDepth")
private fun setupThumbnailForImage(thumbnailImageView: ImageView, file: OCFile) {
var thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache(file.remoteId.toString())
if (thumbnail != null && !file.isUpdateThumbnailNeeded) {
thumbnailImageView.setImageBitmap(thumbnail)
} else {
// generate new Thumbnail
if (ThumbnailsCacheManager.cancelPotentialThumbnailWork(file, thumbnailImageView)) {
val task = ThumbnailGenerationTask(thumbnailImageView, storageManager, user)
if (thumbnail == null) {
thumbnail = if (MimeTypeUtil.isVideo(file)) {
ThumbnailsCacheManager.mDefaultVideo
} else {
ThumbnailsCacheManager.mDefaultImg
}
}
val asyncDrawable = AsyncThumbnailDrawable(
context.resources,
thumbnail,
task
)
thumbnailImageView.setImageDrawable(asyncDrawable)
@Suppress("DEPRECATION")
task.execute(ThumbnailGenerationTaskObject(file, file.remoteId))
}
}
}
private fun setupDefaultThumbnail(thumbnailImageView: ImageView, file: OCFile) {
val icon = MimeTypeUtil.getFileTypeIcon(
file.mimeType,
file.fileName,
context,
viewThemeUtils
)
thumbnailImageView.setImageDrawable(icon)
}
override fun getItemCount() = filteredFiles.size
}

View file

@ -1,156 +0,0 @@
/*
* ownCloud Android client application
*
* @author Tobias Kaminsky
* Copyright (C) 2016 ownCloud Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* 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 com.owncloud.android.ui.adapter;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import com.nextcloud.client.account.User;
import com.nextcloud.client.preferences.DarkMode;
import com.owncloud.android.R;
import com.owncloud.android.datamodel.FileDataStorageManager;
import com.owncloud.android.datamodel.OCFile;
import com.owncloud.android.datamodel.SyncedFolderProvider;
import com.owncloud.android.datamodel.ThumbnailsCacheManager;
import com.owncloud.android.datamodel.ThumbnailsCacheManager.AsyncThumbnailDrawable;
import com.owncloud.android.utils.DisplayUtils;
import com.owncloud.android.utils.MimeTypeUtil;
import com.owncloud.android.utils.theme.ViewThemeUtils;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class UploaderAdapter extends SimpleAdapter {
private final Context mContext;
private final User user;
private final FileDataStorageManager mStorageManager;
private final LayoutInflater inflater;
private final ViewThemeUtils viewThemeUtils;
private SyncedFolderProvider syncedFolderProvider;
public UploaderAdapter(Context context,
List<? extends Map<String, ?>> data,
int resource,
String[] from,
int[] to,
FileDataStorageManager storageManager,
User user,
SyncedFolderProvider syncedFolderProvider,
ViewThemeUtils viewThemeUtils) {
super(context, data, resource, from, to);
this.user = user;
mStorageManager = storageManager;
mContext = context;
this.syncedFolderProvider = syncedFolderProvider;
inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.viewThemeUtils = viewThemeUtils;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View vi = convertView;
if (convertView == null) {
vi = inflater.inflate(R.layout.uploader_list_item_layout, parent, false);
}
HashMap<String, OCFile> data = (HashMap<String, OCFile>) getItem(position);
OCFile file = data.get("dirname");
TextView filename = vi.findViewById(R.id.filename);
filename.setText(file.getFileName());
ImageView fileIcon = vi.findViewById(R.id.thumbnail);
fileIcon.setTag(file.getFileId());
TextView lastModV = vi.findViewById(R.id.last_mod);
lastModV.setText(DisplayUtils.getRelativeTimestamp(mContext, file.getModificationTimestamp()));
TextView fileSizeV = vi.findViewById(R.id.file_size);
TextView fileSizeSeparatorV = vi.findViewById(R.id.file_separator);
if(!file.isFolder()) {
fileSizeV.setVisibility(View.VISIBLE);
fileSizeSeparatorV.setVisibility(View.VISIBLE);
fileSizeV.setText(DisplayUtils.bytesToHumanReadable(file.getFileLength()));
} else {
fileSizeV.setVisibility(View.GONE);
fileSizeSeparatorV.setVisibility(View.GONE);
}
if (file.isFolder()) {
boolean isAutoUploadFolder = SyncedFolderProvider.isAutoUploadFolder(syncedFolderProvider, file, user);
boolean isDarkModeActive = syncedFolderProvider.getPreferences().isDarkModeEnabled();
Integer overlayIconId = file.getFileOverlayIconId(isAutoUploadFolder);
final LayerDrawable icon = MimeTypeUtil.getFileIcon(isDarkModeActive, overlayIconId, mContext, viewThemeUtils);
fileIcon.setImageDrawable(icon);
} else {
// get Thumbnail if file is image
if (MimeTypeUtil.isImage(file) && file.getRemoteId() != null) {
// Thumbnail in Cache?
Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache(
String.valueOf(file.getRemoteId())
);
if (thumbnail != null && !file.isUpdateThumbnailNeeded()) {
fileIcon.setImageBitmap(thumbnail);
} else {
// generate new Thumbnail
if (ThumbnailsCacheManager.cancelPotentialThumbnailWork(file, fileIcon)) {
final ThumbnailsCacheManager.ThumbnailGenerationTask task =
new ThumbnailsCacheManager.ThumbnailGenerationTask(fileIcon, mStorageManager, user);
if (thumbnail == null) {
if (MimeTypeUtil.isVideo(file)) {
thumbnail = ThumbnailsCacheManager.mDefaultVideo;
} else {
thumbnail = ThumbnailsCacheManager.mDefaultImg;
}
}
final AsyncThumbnailDrawable asyncDrawable = new AsyncThumbnailDrawable(
mContext.getResources(),
thumbnail,
task
);
fileIcon.setImageDrawable(asyncDrawable);
task.execute(new ThumbnailsCacheManager.ThumbnailGenerationTaskObject(file, file.getRemoteId()));
}
}
} else {
final Drawable icon = MimeTypeUtil.getFileTypeIcon(file.getMimeType(),
file.getFileName(),
mContext,
viewThemeUtils);
fileIcon.setImageDrawable(icon);
}
}
return vi;
}
}

View file

@ -18,13 +18,9 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.owncloud.android.ui.events;
package com.owncloud.android.ui.events
/**
* Event that notifies that an account was removed
*/
public class AccountRemovedEvent {
}
class AccountRemovedEvent

View file

@ -15,12 +15,11 @@
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* along with this program. If not, see <http:></http:>//www.gnu.org/licenses/>.
*/
package com.owncloud.android.ui.events;
package com.owncloud.android.ui.events
/**
* Currently a dummy event to restore grid view, sort, and search
*/
public class ChangeMenuEvent {
}
class ChangeMenuEvent

View file

@ -18,16 +18,9 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.owncloud.android.ui.events;
package com.owncloud.android.ui.events
/**
* Event for refreshing comment state of a file
*/
public class CommentsEvent {
public final String remoteId;
public CommentsEvent(String remoteId) {
this.remoteId = remoteId;
}
}
class CommentsEvent(val remoteId: String)

View file

@ -15,12 +15,11 @@
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* along with this program. If not, see <http:></http:>//www.gnu.org/licenses/>.
*/
package com.owncloud.android.ui.events;
package com.owncloud.android.ui.events
/**
* Dummy drawer event
*/
public class DummyDrawerEvent {
}
class DummyDrawerEvent

View file

@ -1,37 +0,0 @@
/*
* Nextcloud Android client application
*
* @author Tobias Kaminsky
* Copyright (C) 2017 Tobias Kaminsky
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.owncloud.android.ui.events;
/**
* Event for set folder as encrypted/decrypted
*/
public class EncryptionEvent {
public final long localId;
public final String remotePath;
public final String remoteId;
public final boolean shouldBeEncrypted;
public EncryptionEvent(long localId, String remoteId, String remotePath, boolean shouldBeEncrypted) {
this.localId = localId;
this.remoteId = remoteId;
this.remotePath = remotePath;
this.shouldBeEncrypted = shouldBeEncrypted;
}
}

View file

@ -0,0 +1,30 @@
/*
* Nextcloud Android client application
*
* @author Tobias Kaminsky
* Copyright (C) 2017 Tobias Kaminsky
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.owncloud.android.ui.events
/**
* Event for set folder as encrypted/decrypted
*/
class EncryptionEvent(
val localId: Long,
val remoteId: String,
val remotePath: String,
val shouldBeEncrypted: Boolean
)

View file

@ -1,33 +0,0 @@
/**
* Nextcloud Android client application
*
* @author Mario Danic
* Copyright (C) 2017 Mario Danic
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.owncloud.android.ui.events;
/**
* Event for making favoriting work
*/
public class FavoriteEvent {
public final String remotePath;
public final boolean shouldFavorite;
public FavoriteEvent(String remotePath, boolean shouldFavorite) {
this.remotePath = remotePath;
this.shouldFavorite = shouldFavorite;
}
}

View file

@ -15,14 +15,11 @@
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* along with this program. If not, see <http:></http:>//www.gnu.org/licenses/>.
*/
package com.owncloud.android.ui.events;
package com.owncloud.android.ui.events
public class VCardToggleEvent {
public boolean showRestoreButton;
public VCardToggleEvent(boolean showRestore) {
this.showRestoreButton = showRestore;
}
}
/**
* Event for making favoriting work
*/
class FavoriteEvent(val remotePath: String, val shouldFavorite: Boolean)

View file

@ -1,35 +0,0 @@
/**
* Nextcloud Android client application
*
* @author Mario Danic
* Copyright (C) 2017 Mario Danic
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.owncloud.android.ui.events;
import com.owncloud.android.datamodel.SyncedFolder;
public class InitiateSyncedFolder {
private final SyncedFolder syncedFolder;
public InitiateSyncedFolder(SyncedFolder syncedFolder) {
this.syncedFolder = syncedFolder;
}
public SyncedFolder getSyncedFolder() {
return syncedFolder;
}
}

View file

@ -1,33 +0,0 @@
/**
* Nextcloud Android client application
*
* @author Mario Danic
* Copyright (C) 2017 Mario Danic
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.owncloud.android.ui.events;
import android.view.MenuItem;
/**
* Menu item click event
*/
public class MenuItemClickEvent {
public final MenuItem menuItem;
public MenuItemClickEvent(MenuItem menuItem) {
this.menuItem = menuItem;
}
}

View file

@ -17,10 +17,9 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.owncloud.android.ui.events;
package com.owncloud.android.ui.events
/**
* Event to send push token where it belongs
*/
public class TokenPushEvent {
}
class TokenPushEvent

View file

@ -0,0 +1,22 @@
/**
* Nextcloud Android client application
*
* @author Mario Danic
* Copyright (C) 2017 Mario Danic
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http:></http:>//www.gnu.org/licenses/>.
*/
package com.owncloud.android.ui.events
class VCardToggleEvent(var showRestoreButton: Boolean)

View file

@ -783,13 +783,13 @@ public class FileDetailFragment extends FileFragment implements OnClickListener,
OwnCloudClient client = clientFactory.create(user);
ToggleFavoriteRemoteOperation toggleFavoriteOperation = new ToggleFavoriteRemoteOperation(
event.shouldFavorite, event.remotePath);
event.getShouldFavorite(), event.getRemotePath());
RemoteOperationResult remoteOperationResult = toggleFavoriteOperation.execute(client);
if (remoteOperationResult.isSuccess()) {
getFile().setFavorite(event.shouldFavorite);
OCFile file = storageManager.getFileByEncryptedRemotePath(event.remotePath);
file.setFavorite(event.shouldFavorite);
getFile().setFavorite(event.getShouldFavorite());
OCFile file = storageManager.getFileByEncryptedRemotePath(event.getRemotePath());
file.setFavorite(event.getShouldFavorite());
storageManager.saveFile(file);
}

View file

@ -1588,7 +1588,7 @@ public class OCFileListFragment extends ExtendedListFragment implements
@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void onMessageEvent(CommentsEvent event) {
mAdapter.refreshCommentsCount(event.remoteId);
mAdapter.refreshCommentsCount(event.getRemoteId());
}
@Subscribe(threadMode = ThreadMode.BACKGROUND)
@ -1598,13 +1598,13 @@ public class OCFileListFragment extends ExtendedListFragment implements
OwnCloudClient client = clientFactory.create(user);
ToggleFavoriteRemoteOperation toggleFavoriteOperation = new ToggleFavoriteRemoteOperation(
event.shouldFavorite, event.remotePath);
event.getShouldFavorite(), event.getRemotePath());
RemoteOperationResult remoteOperationResult = toggleFavoriteOperation.execute(client);
if (remoteOperationResult.isSuccess()) {
boolean removeFromList = currentSearchType == SearchType.FAVORITE_SEARCH && !event.shouldFavorite;
boolean removeFromList = currentSearchType == SearchType.FAVORITE_SEARCH && !event.getShouldFavorite();
setEmptyListMessage(SearchType.FAVORITE_SEARCH);
mAdapter.setFavoriteAttributeForItemID(event.remotePath, event.shouldFavorite, removeFromList);
mAdapter.setFavoriteAttributeForItemID(event.getRemotePath(), event.getShouldFavorite(), removeFromList);
}
} catch (ClientFactory.CreationException e) {
@ -1692,7 +1692,7 @@ public class OCFileListFragment extends ExtendedListFragment implements
String privateKey = arbitraryDataProvider.getValue(user, EncryptionUtils.PRIVATE_KEY);
FileDataStorageManager storageManager = mContainerActivity.getStorageManager();
OCFile file = storageManager.getFileByRemoteId(event.remoteId);
OCFile file = storageManager.getFileByRemoteId(event.getRemoteId());
if (publicKey.isEmpty() || privateKey.isEmpty()) {
Log_OC.d(TAG, "no public key for " + user.getAccountName());
@ -1706,10 +1706,10 @@ public class OCFileListFragment extends ExtendedListFragment implements
dialog.show(getParentFragmentManager(), SETUP_ENCRYPTION_DIALOG_TAG);
} else {
encryptFolder(file,
event.localId,
event.remoteId,
event.remotePath,
event.shouldBeEncrypted,
event.getLocalId(),
event.getRemoteId(),
event.getRemotePath(),
event.getShouldBeEncrypted(),
publicKey,
privateKey);
}

View file

@ -270,7 +270,7 @@ public class BackupListFragment extends FileFragment implements Injectable {
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(VCardToggleEvent event) {
if (event.showRestoreButton) {
if (event.getShowRestoreButton()) {
binding.contactlistRestoreSelectedContainer.setVisibility(View.VISIBLE);
} else {
binding.contactlistRestoreSelectedContainer.setVisibility(View.GONE);

View file

@ -436,6 +436,8 @@ public class PreviewImageFragment extends FileFragment implements Injectable {
seeDetails();
} else if (itemId == R.id.action_download_file || itemId == R.id.action_sync_file) {
containerActivity.getFileOperationsHelper().syncFile(getFile());
}else if(itemId == R.id.action_cancel_sync){
containerActivity.getFileOperationsHelper().cancelTransference(getFile());
} else if (itemId == R.id.action_set_as_wallpaper) {
containerActivity.getFileOperationsHelper().setPictureAs(getFile(), getImageView());
} else if (itemId == R.id.action_export_file) {

View file

@ -482,6 +482,8 @@ public class PreviewMediaFragment extends FileFragment implements OnTouchListene
seeDetails();
} else if (itemId == R.id.action_sync_file) {
containerActivity.getFileOperationsHelper().syncFile(getFile());
} else if (itemId == R.id.action_cancel_sync) {
containerActivity.getFileOperationsHelper().cancelTransference(getFile());
} else if (itemId == R.id.action_stream_media) {
containerActivity.getFileOperationsHelper().streamMediaFile(getFile());
} else if (itemId == R.id.action_export_file) {

View file

@ -330,6 +330,8 @@ public class PreviewTextFileFragment extends PreviewTextFragment {
seeDetails();
} else if (itemId == R.id.action_sync_file) {
containerActivity.getFileOperationsHelper().syncFile(getFile());
} else if(itemId == R.id.action_cancel_sync){
containerActivity.getFileOperationsHelper().cancelTransference(getFile());
} else if (itemId == R.id.action_edit) {
containerActivity.getFileOperationsHelper().openFileWithTextEditor(getFile(), getContext());
}

View file

@ -34,10 +34,11 @@
android:layout_height="0dp"
android:layout_weight="1">
<ListView
<androidx.recyclerview.widget.RecyclerView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/bg_default"
android:divider="@color/transparent"
android:dividerHeight="0dip"

View file

@ -891,6 +891,7 @@
<string name="upload_lock_failed">فشل قفّل المجلد</string>
<string name="upload_old_android">التشفير ممكن فقط مع &gt;= Android 5.0</string>
<string name="upload_query_move_foreign_files">يمنع وجود مساحة غير كافية نسخ الملفات المحددة إلى المجلد %1$s. هل ترغب في نقلهم إلى هناك بدلاً من ذلك؟</string>
<string name="upload_quota_exceeded">الحصة التخزينية تمّ استنفاذها</string>
<string name="upload_scan_doc_upload">مسح مستند عبر الكاميرا</string>
<string name="upload_sync_conflict">تعارض المزامنة ، يرجى حلها يدويًا</string>
<string name="upload_unknown_error">خطأ غير معروف</string>

View file

@ -884,6 +884,7 @@
<string name="upload_lock_failed">Uzamčení složky se nezdařilo</string>
<string name="upload_old_android">Šifrování je možné pouze na systému Android verze 5.0 a novějším</string>
<string name="upload_query_move_foreign_files">Pro zkopírování vybraných souborů do složky %1$s není dostatek volného místa. Chcete je tam namísto toho přesunout?</string>
<string name="upload_quota_exceeded">Kvóta úložiště překročena</string>
<string name="upload_scan_doc_upload">Naskenovat dokument kamerou</string>
<string name="upload_sync_conflict">Konflikt synchronizace vyřešte ručně</string>
<string name="upload_unknown_error">Neznámá chyba</string>

View file

@ -885,6 +885,7 @@
<string name="upload_lock_failed">Fehler beim Sperren des Ordners</string>
<string name="upload_old_android">Verschlüsselung ist nur möglich mit &gt;= Android 5.0</string>
<string name="upload_query_move_foreign_files">Es steht nicht genügend Speicherplatz zur Verfügung, um die ausgewählten Dateien in das Verzeichnis %1$s zu kopieren. Sollen diese stattdessen verschoben werden?</string>
<string name="upload_quota_exceeded">Speicherkontingent überschritten</string>
<string name="upload_scan_doc_upload">Dokument von der Kamera scannen</string>
<string name="upload_sync_conflict">Synchronisierungskonflikt, bitte manuell beheben</string>
<string name="upload_unknown_error">Unbekannter Fehler</string>

View file

@ -885,6 +885,7 @@
<string name="upload_lock_failed">Produciuse un fallo ao bloquear o cartafol</string>
<string name="upload_old_android">O cifrado só é posíbel con &gt;= Android 5.0</string>
<string name="upload_query_move_foreign_files">Non hai espazo abondo para copiar os ficheiros seleccionados no cartafol %1$s. No canto diso, gustaríalle movelos?</string>
<string name="upload_quota_exceeded">Superouse a cota de almacenamento</string>
<string name="upload_scan_doc_upload">Escanear o documento dende a cámara</string>
<string name="upload_sync_conflict">Conflito ao sincronizar, resólvao manualmente</string>
<string name="upload_unknown_error">Produciuse un erro descoñecido</string>

View file

@ -884,6 +884,7 @@
<string name="upload_lock_failed">Неуспело закључавање фасцикле</string>
<string name="upload_old_android">Шифровање је могуће само са &gt;= Андроидом 5.0</string>
<string name="upload_query_move_foreign_files">Недостатак простора спречава копирање фајлова у фасциклу %1$s. Желите ли да их преместите тамо?</string>
<string name="upload_quota_exceeded">Прекорачена је квота за складиште</string>
<string name="upload_scan_doc_upload">Скенирање документа камером</string>
<string name="upload_sync_conflict">Сукоб синхронизације. Разрешите га ручно</string>
<string name="upload_unknown_error">Непозната грешка</string>

View file

@ -731,7 +731,7 @@
<string name="shared_icon_share">поділитися</string>
<string name="shared_icon_shared">надано доступ</string>
<string name="shared_icon_shared_via_link">доступ надано за посиланням</string>
<string name="shared_with_you_by">%1$s поділився з вами</string>
<string name="shared_with_you_by">%1$s поділив(-ла-)ся з вами</string>
<string name="sharee_add_failed">Помилка додавання користувача, з яким ви хочете поділитися</string>
<string name="show_images">Показувати зображення</string>
<string name="show_video">Показувати відео</string>
@ -793,7 +793,7 @@
<string name="sub_folder_rule_month">Рік/місяць</string>
<string name="sub_folder_rule_year">Рік</string>
<string name="subject_shared_with_you">Вам було надано доступ до \"%1$s\"</string>
<string name="subject_user_shared_with_you">%1$s поділився %2$s з вами</string>
<string name="subject_user_shared_with_you">%1$s поділив(-ла-)ся %2$s з вами</string>
<string name="subtitle_photos_only">Лише зображення</string>
<string name="subtitle_photos_videos">Зображення та відео</string>
<string name="subtitle_videos_only">Лише відео</string>

View file

@ -887,6 +887,7 @@
<string name="upload_lock_failed">锁定文件夹失败</string>
<string name="upload_old_android">加密功能仅适用于安卓 5.0 及以上版本</string>
<string name="upload_query_move_foreign_files">空间不足将阻止将所选文件复制到%1$s文件夹中。 你想把它们移到那里吗?</string>
<string name="upload_quota_exceeded">超出存储限额</string>
<string name="upload_scan_doc_upload">使用相机扫描文档</string>
<string name="upload_sync_conflict">同步时发生异常,请手动同步</string>
<string name="upload_unknown_error">未知错误</string>

View file

@ -884,6 +884,7 @@
<string name="upload_lock_failed">鎖定資料夾失敗</string>
<string name="upload_old_android">加密功能僅適用於 Android 5.0 及更新版本</string>
<string name="upload_query_move_foreign_files">空間不足以將選擇的檔案複製到 %1$s 資料夾,是否要改成移動它們?</string>
<string name="upload_quota_exceeded">超過儲存空間配額</string>
<string name="upload_scan_doc_upload">使用相機掃描文件</string>
<string name="upload_sync_conflict">同步發生衝突,請手動處理</string>
<string name="upload_unknown_error">未知的錯誤</string>

View file

@ -1,6 +1,6 @@
buildscript {
ext {
androidPluginVersion = '8.1.4'
androidPluginVersion = '8.2.0'
appCompatVersion = '1.6.1'
jacoco_version = '0.8.10'
kotlin_version = '1.8.22'

View file

@ -4,7 +4,6 @@ NC_TEST_SERVER_USERNAME=test
NC_TEST_SERVER_PASSWORD=test
android.enableJetifier=true
android.useAndroidX=true
android.defaults.buildfeatures.buildconfig=true
android.nonTransitiveRClass=false
android.nonFinalResIds=false
#android.debug.obsoleteApi=true

View file

@ -1,6 +1,6 @@
#Fri Jan 13 08:21:45 CET 2023
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME

View file

@ -1,2 +1,2 @@
DO NOT TOUCH; GENERATED BY DRONE
<span class="mdl-layout-title">Lint Report: 71 warnings</span>
<span class="mdl-layout-title">Lint Report: 9 errors and 75 warnings</span>